diff --git a/lib/dbi/subscription.c b/lib/dbi/subscription.c index e86fc9707..3c8e053bc 100644 --- a/lib/dbi/subscription.c +++ b/lib/dbi/subscription.c @@ -393,6 +393,10 @@ int ogs_dbi_subscription_data(char *supi, BSON_ITER_HOLDS_INT32(&iter)) { subscription_data->subscriber_status = bson_iter_int32(&iter); + } else if (!strcmp(key, "operator_determined_barring") && + BSON_ITER_HOLDS_INT32(&iter)) { + subscription_data->operator_determined_barring = + bson_iter_int32(&iter); } else if (!strcmp(key, "network_access_mode") && BSON_ITER_HOLDS_INT32(&iter)) { subscription_data->network_access_mode = diff --git a/lib/diameter/s6a/message.c b/lib/diameter/s6a/message.c index e64379685..1f725dfc0 100644 --- a/lib/diameter/s6a/message.c +++ b/lib/diameter/s6a/message.c @@ -54,6 +54,7 @@ struct dict_object *ogs_diam_s6a_xres = NULL; struct dict_object *ogs_diam_s6a_autn = NULL; struct dict_object *ogs_diam_s6a_kasme = NULL; struct dict_object *ogs_diam_s6a_subscriber_status = NULL; +struct dict_object *ogs_diam_s6a_operator_determined_barring = NULL; struct dict_object *ogs_diam_s6a_ambr = NULL; struct dict_object *ogs_diam_s6a_network_access_mode = NULL; struct dict_object *ogs_diam_s6a_access_restriction_data = NULL; @@ -151,6 +152,7 @@ int ogs_diam_s6a_init(void) CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Served-Party-IP-Address", &ogs_diam_s6a_served_party_ip_address); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Data", &ogs_diam_s6a_subscription_data); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscriber-Status", &ogs_diam_s6a_subscriber_status); + CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Operator-Determined-Barring", &ogs_diam_s6a_operator_determined_barring); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Network-Access-Mode", &ogs_diam_s6a_network_access_mode); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Access-Restriction-Data", &ogs_diam_s6a_access_restriction_data); CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscribed-Periodic-RAU-TAU-Timer", &ogs_diam_s6a_subscribed_rau_tau_timer); diff --git a/lib/diameter/s6a/message.h b/lib/diameter/s6a/message.h index 6708282e3..5ecf4e369 100644 --- a/lib/diameter/s6a/message.h +++ b/lib/diameter/s6a/message.h @@ -119,6 +119,7 @@ extern struct dict_object *ogs_diam_s6a_xres; extern struct dict_object *ogs_diam_s6a_autn; extern struct dict_object *ogs_diam_s6a_kasme; extern struct dict_object *ogs_diam_s6a_subscriber_status; +extern struct dict_object *ogs_diam_s6a_operator_determined_barring; extern struct dict_object *ogs_diam_s6a_ambr; extern struct dict_object *ogs_diam_s6a_network_access_mode; extern struct dict_object *ogs_diam_s6a_access_restriction_data; diff --git a/lib/proto/types.h b/lib/proto/types.h index fbb15c3e0..50195253b 100644 --- a/lib/proto/types.h +++ b/lib/proto/types.h @@ -685,6 +685,16 @@ typedef struct ogs_subscription_data_s { #define OGS_SUBSCRIBER_STATUS_SERVICE_GRANTED 0 #define OGS_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING 1 uint32_t subscriber_status; +#define OGS_OP_DET_BARRING_ALL_PS_BARRED (1<<0) +#define OGS_OP_DET_BARRING_ROAM_ACC_HPLMN_AP_BARRED (1<<1) +#define OGS_OP_DET_BARRING_ROAM_ACC_VPLMN_AP_BARRED (1<<2) +#define OGS_OP_DET_BARRING_ALL_OUT_CALLS (1<<3) +#define OGS_OP_DET_BARRING_ALL_OUT_INT_CALLS (1<<4) +#define OGS_OP_DET_BARRING_ALL_OUT_INT_CALLS_EXCL_HPLMN_COUNTRY (1<<5) +#define OGS_OP_DET_BARRING_ALL_OUT_INTERZONE_CALLS (1<<6) +#define OGS_OP_DET_BARRING_ALL_OUT_INTERZONE_CALLS_EXCL_HPLMN_COUNTRY (1<<7) +#define OGS_OPD_ETEBARRING_OUT_INT_CALLS_EXCL_EXCL_HPLMN_COUNTRY_AND_INTERZONE_CALLS (1<<8) + uint32_t operator_determined_barring; /* 3GPP TS 29.272 7.3.30 */ #define OGS_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT 0 #define OGS_NETWORK_ACCESS_MODE_RESERVED 1 #define OGS_NETWORK_ACCESS_MODE_ONLY_PACKET 2 diff --git a/misc/db/open5gs-dbctl b/misc/db/open5gs-dbctl index b2a43ace4..79b9affff 100755 --- a/misc/db/open5gs-dbctl +++ b/misc/db/open5gs-dbctl @@ -25,7 +25,7 @@ display_help() { echo " showpretty: shows the list of subscriber in the db in a pretty json tree format" echo " showfiltered: shows {imsi key opc apn ip} information of subscriber" echo " ambr_speed {imsi dl_value dl_unit ul_value ul_unit}: Change AMBR speed from a specific user and the unit values are \"[0=bps 1=Kbps 2=Mbps 3=Gbps 4=Tbps ]\"" - + echo " subscriber_status {imsi subscriber_status_val={0,1} operator_determined_barring={0..8}}: Change TS 29.272 values for Subscriber-Status (7.3.29) and Operator-Determined-Barring (7.3.30)" } @@ -118,6 +118,8 @@ if [ "$1" = "add" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -194,6 +196,8 @@ if [ "$1" = "add" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -325,6 +329,8 @@ if [ "$1" = "addT1" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -464,6 +470,8 @@ if [ "$1" = "addT1" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -598,6 +606,8 @@ if [ "$1" = "add_ue_with_apn" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -678,6 +688,8 @@ if [ "$1" = "add_ue_with_slice" ]; then }, \"access_restriction_data\": 32, \"network_access_mode\": 0, + \"subscriber_status\": 0, + \"operator_determined_barring\": 0, \"subscribed_rau_tau_timer\": 12, \"__v\": 0 } @@ -773,6 +785,21 @@ if [ "$1" = "update_slice" ]; then echo "open5gs-dbctl: incorrect number of args, format is \"open5gs-dbctl update_slice imsi apn sst sd\"" exit 1 fi +if [ "$1" = "subscriber_status" ]; then + if [ "$#" -eq 4 ]; then + IMSI=$2 + SUB_STATUS=$3 + OP_DET_BARRING=$4 + mongosh --eval "db.subscribers.updateOne({ \"imsi\": \"$IMSI\"}, + {\$set: { \"subscriber_status\": $SUB_STATUS, + \"operator_determined_barring\": $OP_DET_BARRING + } + });" $DB_URI + exit $? + fi + echo "open5gs-dbctl: incorrect number of args, format is \"open5gs-dbctl subscriber_status imsi subscriber_status_val={0,1} operator_determined_barring={0..8}" + exit 1 +fi if [ "$1" = "showall" ]; then mongosh --eval "db.subscribers.find()" $DB_URI exit $? diff --git a/misc/db/python/README.md b/misc/db/python/README.md index 9b9f312ee..5c4759a1b 100644 --- a/misc/db/python/README.md +++ b/misc/db/python/README.md @@ -39,6 +39,7 @@ sub_data = { "subscribed_rau_tau_timer": 12, "network_access_mode": 0, "subscriber_status": 0, + "operator_determined_barring": 0, "access_restriction_data": 32, "slice" : slice_data, "ambr": {"uplink": {"value": 1, "unit": 3}, "downlink": {"value": 1, "unit": 3}}, diff --git a/misc/db/python/test_SchemaUpdater.py b/misc/db/python/test_SchemaUpdater.py index 2963a0866..141b89384 100644 --- a/misc/db/python/test_SchemaUpdater.py +++ b/misc/db/python/test_SchemaUpdater.py @@ -43,13 +43,15 @@ class TestSchemaUpdater(unittest.TestCase): 'opc': 'iamatransparentsecretopcstring' }, 'subscribed_rau_tau_timer': 12, - 'subscriber_status': 0 + 'subscriber_status': 0, + "operator_determined_barring": 0, } def test_top_level_migration(self): new_sub = SchemaUpdater.create_v1_from_v0(self.legacy_sub) self.assertEqual(new_sub["imsi"], self.legacy_sub["imsi"]) self.assertEqual(new_sub["subscriber_status"], self.legacy_sub["subscriber_status"]) + self.assertEqual(new_sub["operator_determined_barring"], self.legacy_sub["operator_determined_barring"]) self.assertEqual(new_sub["subscribed_rau_tau_timer"], self.legacy_sub["subscribed_rau_tau_timer"]) self.assertEqual(new_sub["network_access_mode"], self.legacy_sub["network_access_mode"]) self.assertEqual(new_sub["access_restriction_data"], self.legacy_sub["access_restriction_data"]) diff --git a/src/hss/hss-context.c b/src/hss/hss-context.c index 742007ce1..9966d77f0 100644 --- a/src/hss/hss-context.c +++ b/src/hss/hss-context.c @@ -1254,6 +1254,12 @@ int hss_handle_change_event(const bson_t *document) send_idr_flag = true; subdatamask = (subdatamask | OGS_DIAM_S6A_SUBDATA_SUB_STATUS); + } else if (!strncmp(child2_key, + "operator_determined_barring", + strlen("operator_determined_barring"))) { + send_idr_flag = true; + subdatamask = (subdatamask | + OGS_DIAM_S6A_SUBDATA_SUB_STATUS); } else if (!strncmp(child2_key, "network_access_mode", strlen("network_access_mode"))) { diff --git a/src/hss/hss-s6a-path.c b/src/hss/hss-s6a-path.c index cca7c2a7d..16dc6f3d4 100644 --- a/src/hss/hss-s6a-path.c +++ b/src/hss/hss-s6a-path.c @@ -303,7 +303,7 @@ static int hss_s6a_avp_add_subscription_data( struct avp *avp_msisdn, *avp_a_msisdn; struct avp *avp_access_restriction_data; - struct avp *avp_subscriber_status, *avp_network_access_mode; + struct avp *avp_subscriber_status, *avp_operator_determined_barring, *avp_network_access_mode; struct avp *avp_ambr, *avp_max_bandwidth_ul, *avp_max_bandwidth_dl; struct avp *avp_rau_tau_timer; @@ -373,6 +373,17 @@ static int hss_s6a_avp_add_subscription_data( ogs_assert(ret == 0); ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_subscriber_status); ogs_assert(ret == 0); + + if (subscription_data->subscriber_status == OGS_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING) { + ret = fd_msg_avp_new( + ogs_diam_s6a_operator_determined_barring, 0, &avp_operator_determined_barring); + ogs_assert(ret == 0); + val.i32 = subscription_data->operator_determined_barring; + ret = fd_msg_avp_setvalue(avp_operator_determined_barring, &val); + ogs_assert(ret == 0); + ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_operator_determined_barring); + ogs_assert(ret == 0); + } } if (subdatamask & OGS_DIAM_S6A_SUBDATA_NAM) { diff --git a/tests/common/context.c b/tests/common/context.c index 1f1bfa5c5..6803681cc 100644 --- a/tests/common/context.c +++ b/tests/common/context.c @@ -1511,6 +1511,7 @@ bson_t *test_db_new_simple(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -1615,6 +1616,7 @@ bson_t *test_db_new_qos_flow(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -1743,6 +1745,7 @@ bson_t *test_db_new_session(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -1893,6 +1896,7 @@ bson_t *test_db_new_ims(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -2270,6 +2274,7 @@ bson_t *test_db_new_slice_with_same_dnn(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -2647,6 +2652,7 @@ bson_t *test_db_new_slice_with_different_dnn(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); @@ -2801,6 +2807,7 @@ bson_t *test_db_new_non3gpp(test_ue_t *test_ue) "subscribed_rau_tau_timer", BCON_INT32(12), "network_access_mode", BCON_INT32(0), "subscriber_status", BCON_INT32(0), + "operator_determined_barring", BCON_INT32(0), "access_restriction_data", BCON_INT32(32) ); ogs_assert(doc); diff --git a/webui/server/models/subscriber.js b/webui/server/models/subscriber.js index 744ac3e43..830c7e2de 100644 --- a/webui/server/models/subscriber.js +++ b/webui/server/models/subscriber.js @@ -91,6 +91,10 @@ const Subscriber = new Schema({ $type: Number, default: 0 // Service Granted }, + operator_determined_barring: { + $type: Number, + default: 0 // No barring + }, network_access_mode: { $type: Number, default: 0 // Packet and Circuit diff --git a/webui/src/components/Subscriber/Edit.js b/webui/src/components/Subscriber/Edit.js index 999532b46..ea874c82b 100644 --- a/webui/src/components/Subscriber/Edit.js +++ b/webui/src/components/Subscriber/Edit.js @@ -120,6 +120,30 @@ const schema = { } } }, + "subscriber_status": { + "type": "number", + "title": "Subscriber Status (TS 29.272 7.3.29)", + "enum": [ 0, 1 ], + "enumNames": ["SERVICE_GRANTED", "OPERATOR_DETERMINED_BARRING"], + "default": 0, + }, + "operator_determined_barring": { + "type": "number", + "title": "Operator Determined Barring (TS 29.272 7.3.30)", + "enum": [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ], + "enumNames": [ + "(0) All Packet Oriented Services Barred", + "(1) Roamer Access HPLMN-AP Barred", + "(2) Roamer Access to VPLMN-AP Barred", + "(3) Barring of all outgoing calls", + "(4) Barring of all outgoing international calls", + "(5) Barring of all outgoing international calls except those directed to the home PLMN country", + "(6) Barring of all outgoing inter-zonal calls", + "(7) Barring of all outgoing inter-zonal calls except those directed to the home PLMN country", + "(8) Barring of all outgoing international calls except those directed to the home PLMN country and Barring of all outgoing inter-zonal calls" + ], + "default": 0, + }, "slice": { "type": "array", "title": "Slice Configurations", @@ -503,6 +527,12 @@ const uiSchema = { }, } }, + "subscriber_status" : { + classNames: "col-xs-7", + }, + "operator_determined_barring" : { + classNames: "col-xs-7", + }, "slice": { classNames: "col-xs-12", "items": { diff --git a/webui/src/components/Subscriber/View.js b/webui/src/components/Subscriber/View.js index 7b48a3913..867e79bdd 100644 --- a/webui/src/components/Subscriber/View.js +++ b/webui/src/components/Subscriber/View.js @@ -175,6 +175,8 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on const purge_flag = (subscriber || {}).purge_flag; const security = ((subscriber || {}).security || {}); const ambr = ((subscriber || {}).ambr || {}); + const subscriber_status = (subscriber || {}).subscriber_status; + const operator_determined_barring = (subscriber || {}).operator_determined_barring; const slice_list = ((subscriber || {}).slice || []); return ( @@ -260,6 +262,23 @@ const View = ({ visible, disableOnClickOutside, subscriber, onEdit, onDelete, on +
+
+
+ +
+
+
+ {subscriber_status == 0 ? ( "SERVICE_GRANTED (0)" ) : ( "OPERATOR_DETERMINED_BARRING (1)" )} + Subscriber Status (TS 29.272 7.3.29) +
+
+ {operator_determined_barring} + Operator Determined Barring (TS 29.272 7.3.30) +
+
+
+
{mme_host && mme_host.length !== 0 &&