Change in libosmocore[master]: bssgp2: Encoding + Decoding functions for BVC and MS flow control

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Thu Dec 10 10:07:15 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/21610 )

Change subject: bssgp2: Encoding + Decoding functions for BVC and MS flow control
......................................................................

bssgp2: Encoding + Decoding functions for BVC and MS flow control

Change-Id: I9c89bb1c03550930c07aad7ff8f67129ee7a6320
Related: OS#4891
---
M include/osmocom/gprs/gprs_bssgp2.h
M include/osmocom/gprs/protocol/gsm_08_18.h
M src/gb/gprs_bssgp2.c
M src/gb/libosmogb.map
4 files changed, 259 insertions(+), 0 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

Objections:
  daniel: I would prefer this is not merged as is



diff --git a/include/osmocom/gprs/gprs_bssgp2.h b/include/osmocom/gprs/gprs_bssgp2.h
index 0ab3619..bf814cb 100644
--- a/include/osmocom/gprs/gprs_bssgp2.h
+++ b/include/osmocom/gprs/gprs_bssgp2.h
@@ -4,10 +4,41 @@
 #include <osmocom/gprs/protocol/gsm_08_18.h>
 #include <osmocom/gprs/gprs_ns2.h>
 
+struct bssgp2_flow_ctrl;
 struct gprs_ns2_inst;
 struct gprs_ra_id;
 struct msgb;
 
+struct bssgp2_flow_ctrl {
+	uint8_t tag;
+	/* maximum bucket size (Bmax) in bytes */
+	uint64_t bucket_size_max;
+	/*! bucket leak rate in _bytes_ per second */
+	uint64_t bucket_leak_rate;
+	/* percentage how full the given bucket is */
+	uint8_t bucket_full_ratio;
+	bool bucket_full_ratio_present;
+	union {
+		/*! FC-BVC specifi members */
+		struct {
+			/*! default maximum bucket size per MS in bytes */
+			uint64_t bmax_default_ms;
+			/*! default bucket leak rate (R) for MS flow control bucket */
+			uint64_t r_default_ms;
+
+			/*! average milliseconds of queueing delay for a BVC */
+			uint32_t measurement;
+			bool measurement_present;
+		} bvc;
+		/*! FC-MS specifi members */
+		struct {
+			/*! TLLI of the MS */
+			uint32_t tlli;
+		} ms;
+	} u;
+};
+
+
 int bssgp2_nsi_tx_ptp(struct gprs_ns2_inst *nsi, uint16_t nsei, uint16_t bvci,
 		      struct msgb *msg, uint32_t lsp);
 
@@ -29,3 +60,11 @@
 				      const uint8_t *feat_bm, const uint8_t *ext_feat_bm);
 
 struct msgb *bssgp2_enc_status(uint8_t cause, const uint16_t *bvci, const struct msgb *orig_msg);
+
+
+int bssgp2_dec_fc_bvc(struct bssgp2_flow_ctrl *fc, const struct tlv_parsed *tp);
+struct msgb *bssgp2_enc_fc_bvc(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
+struct msgb *bssgp2_enc_fc_bvc_ack(uint8_t tag);
+int bssgp2_dec_fc_ms(struct bssgp2_flow_ctrl *fc, struct tlv_parsed *tp);
+struct msgb *bssgp2_enc_fc_ms(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran);
+struct msgb *bssgp2_enc_fc_ms_ack(uint32_t tlli, uint8_t tag);
diff --git a/include/osmocom/gprs/protocol/gsm_08_18.h b/include/osmocom/gprs/protocol/gsm_08_18.h
index 0ce28f5..466b0c5 100644
--- a/include/osmocom/gprs/protocol/gsm_08_18.h
+++ b/include/osmocom/gprs/protocol/gsm_08_18.h
@@ -341,3 +341,11 @@
 #define	BSSGP_XFEAT_DCN		0x20	/* Dedicated CN */
 #define	BSSGP_XFEAT_eDRX	0x40	/* eDRX */
 #define	BSSGP_XFEAT_MSAD	0x80	/* MS-assisted Dedicated CN selection */
+
+/* Flow Control Granularity (Section 11.3.102) */
+enum bssgp_fc_granularity {
+	BSSGP_FC_GRAN_100	= 0,
+	BSSGP_FC_GRAN_1000	= 1,
+	BSSGP_FC_GRAN_10000	= 2,
+	BSSGP_FC_GRAN_100000	= 3,
+};
diff --git a/src/gb/gprs_bssgp2.c b/src/gb/gprs_bssgp2.c
index e741fb4..a54a8d9 100644
--- a/src/gb/gprs_bssgp2.c
+++ b/src/gb/gprs_bssgp2.c
@@ -238,3 +238,209 @@
 
 	return msg;
 }
+
+static const unsigned int bssgp_fc_gran_tbl[] = {
+	[BSSGP_FC_GRAN_100]	= 100,
+	[BSSGP_FC_GRAN_1000]	= 1000,
+	[BSSGP_FC_GRAN_10000]	= 10000,
+	[BSSGP_FC_GRAN_100000]	= 100000,
+};
+
+/*! Decode a FLOW-CONTROL-BVC PDU as per TS 48.018 Section 10.4.4.
+ *  \param[out] fc caller-allocated memory for parsed output
+ *  \param[in] tp pre-parsed TLVs; caller must ensure mandatory IE presence/length
+ *  \returns 0 on success; negative in case of error */
+int bssgp2_dec_fc_bvc(struct bssgp2_flow_ctrl *fc, const struct tlv_parsed *tp)
+{
+	unsigned int granularity = 100;
+
+	/* optional "Flow Control Granularity IE" (11.3.102); applies to
+	 * bucket_size_max, bucket_leak_rate and PFC FC params IE */
+	if (TLVP_PRESENT(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY)) {
+		uint8_t gran = *TLVP_VAL(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY);
+		granularity = bssgp_fc_gran_tbl[gran & 3];
+	}
+
+	/* mandatory IEs */
+	fc->tag = *TLVP_VAL(tp, BSSGP_IE_TAG);
+	fc->bucket_size_max = granularity * tlvp_val16be(tp, BSSGP_IE_BVC_BUCKET_SIZE);
+	fc->bucket_leak_rate = (granularity * tlvp_val16be(tp, BSSGP_IE_BUCKET_LEAK_RATE)) / 8;
+	fc->u.bvc.bmax_default_ms = granularity * tlvp_val16be(tp, BSSGP_IE_BMAX_DEFAULT_MS);
+	fc->u.bvc.r_default_ms = (granularity * tlvp_val16be(tp, BSSGP_IE_R_DEFAULT_MS)) / 8;
+
+	/* optional / conditional */
+	if (TLVP_PRESENT(tp, BSSGP_IE_BUCKET_FULL_RATIO)) {
+		fc->bucket_full_ratio_present = true;
+		fc->bucket_full_ratio = *TLVP_VAL(tp, BSSGP_IE_BUCKET_FULL_RATIO);
+	} else {
+		fc->bucket_full_ratio_present = false;
+	}
+
+	if (TLVP_PRESENT(tp, BSSGP_IE_BVC_MEASUREMENT)) {
+		uint16_t val = tlvp_val16be(tp, BSSGP_IE_BVC_MEASUREMENT);
+		fc->u.bvc.measurement_present = true;
+		/* convert from centi-seconds to milli-seconds */
+		if (val == 0xffff)
+			fc->u.bvc.measurement = 0xffffffff;
+		else
+			fc->u.bvc.measurement = val * 10;
+	} else {
+		fc->u.bvc.measurement_present = false;
+	}
+
+	return 0;
+
+}
+
+/*! Encode a FLOW-CONTROL-BVC PDU as per TS 48.018 Section 10.4.4.
+ *  \param[in] fc structure describing to-be-encoded FC parameters
+ *  \param[in] gran if non-NULL: Encode using specified unit granularity
+ *  \returns encoded PDU or NULL in case of error */
+struct msgb *bssgp2_enc_fc_bvc(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran)
+{
+	struct msgb *msg = bssgp_msgb_alloc();
+	struct bssgp_normal_hdr *bgph;
+	unsigned int granularity = 100;
+
+	if (gran)
+		granularity = bssgp_fc_gran_tbl[*gran & 3];
+
+	if (!msg)
+		return NULL;
+
+	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC;
+
+	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &fc->tag);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_BVC_BUCKET_SIZE, fc->bucket_size_max / granularity);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_BUCKET_LEAK_RATE, fc->bucket_leak_rate * 8 / granularity);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_BMAX_DEFAULT_MS, fc->u.bvc.bmax_default_ms / granularity);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_R_DEFAULT_MS, fc->u.bvc.r_default_ms * 8 / granularity);
+
+	if (fc->bucket_full_ratio_present)
+		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO, 1, &fc->bucket_full_ratio);
+
+	if (fc->u.bvc.measurement_present) {
+		uint16_t val;
+		/* convert from ms to cs */
+		if (fc->u.bvc.measurement == 0xffffffff)
+			val = 0xffff;
+		else
+			val = fc->u.bvc.measurement / 10;
+		msgb_tvlv_put_16be(msg, BSSGP_IE_BVC_MEASUREMENT, val);
+	}
+
+	if (gran) {
+		uint8_t val = *gran & 3;
+		msgb_tvlv_put(msg, BSSGP_IE_FLOW_CTRL_GRANULARITY, 1, &val);
+	}
+
+	return msg;
+}
+
+/*! Encode a FLOW-CONTROL-BVC-ACK PDU as per TS 48.018 Section 10.4.4.
+ *  \param[in] tag the tag IE value to encode
+ *  \returns encoded PDU or NULL in case of error */
+struct msgb *bssgp2_enc_fc_bvc_ack(uint8_t tag)
+{
+	struct msgb *msg = bssgp_msgb_alloc();
+	struct bssgp_normal_hdr *bgph;
+
+	if (!msg)
+		return NULL;
+
+	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC_ACK;
+
+	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);
+
+	return msg;
+}
+
+/*! Decode a FLOW-CONTROL-MS PDU as per TS 48.018 Section 10.4.6.
+ *  \param[out] fc caller-allocated memory for parsed output
+ *  \param[in] tp pre-parsed TLVs; caller must ensure mandatory IE presence/length
+ *  \returns 0 on success; negative in case of error */
+int bssgp2_dec_fc_ms(struct bssgp2_flow_ctrl *fc, struct tlv_parsed *tp)
+{
+	unsigned int granularity = 100;
+
+	/* optional "Flow Control Granularity IE" (11.3.102); applies to
+	 * bucket_size_max, bucket_leak_rate and PFC FC params IE */
+	if (TLVP_PRESENT(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY)) {
+		uint8_t gran = *TLVP_VAL(tp, BSSGP_IE_FLOW_CTRL_GRANULARITY);
+		granularity = bssgp_fc_gran_tbl[gran & 3];
+	}
+
+	/* mandatory IEs */
+	fc->u.ms.tlli = tlvp_val32be(tp, BSSGP_IE_TLLI);
+	fc->tag = *TLVP_VAL(tp, BSSGP_IE_TAG);
+	fc->bucket_size_max = granularity * tlvp_val16be(tp, BSSGP_IE_MS_BUCKET_SIZE);
+	fc->bucket_leak_rate = (granularity * tlvp_val16be(tp, BSSGP_IE_BUCKET_LEAK_RATE)) / 8;
+
+	/* optional / conditional */
+	if (TLVP_PRESENT(tp, BSSGP_IE_BUCKET_FULL_RATIO)) {
+		fc->bucket_full_ratio_present = true;
+		fc->bucket_full_ratio = *TLVP_VAL(tp, BSSGP_IE_BUCKET_FULL_RATIO);
+	} else {
+		fc->bucket_full_ratio_present = false;
+	}
+
+	return 0;
+}
+
+/*! Encode a FLOW-CONTROL-MS PDU as per TS 48.018 Section 10.4.6.
+ *  \param[in] fc structure describing to-be-encoded FC parameters
+ *  \param[in] gran if non-NULL: Encode using specified unit granularity
+ *  \returns encoded PDU or NULL in case of error */
+struct msgb *bssgp2_enc_fc_ms(const struct bssgp2_flow_ctrl *fc, enum bssgp_fc_granularity *gran)
+{
+	struct msgb *msg = bssgp_msgb_alloc();
+	struct bssgp_normal_hdr *bgph;
+	unsigned int granularity = 100;
+
+	if (gran)
+		granularity = bssgp_fc_gran_tbl[*gran & 3];
+
+	if (!msg)
+		return NULL;
+
+	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_MS;
+
+	msgb_tvlv_put_32be(msg, BSSGP_IE_TLLI, fc->u.ms.tlli);
+	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &fc->tag);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_MS_BUCKET_SIZE, fc->bucket_size_max / granularity);
+	msgb_tvlv_put_16be(msg, BSSGP_IE_BUCKET_LEAK_RATE, fc->bucket_leak_rate * 8 / granularity);
+
+	if (fc->bucket_full_ratio_present)
+		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO, 1, &fc->bucket_full_ratio);
+
+	if (gran) {
+		uint8_t val = *gran & 3;
+		msgb_tvlv_put(msg, BSSGP_IE_FLOW_CTRL_GRANULARITY, 1, &val);
+	}
+
+	return msg;
+}
+
+/*! Encode a FLOW-CONTROL-BVC-ACK PDU as per TS 48.018 Section 10.4.7.
+ *  \param[in] tlli the TLLI IE value to encode
+ *  \param[in] tag the tag IE value to encode
+ *  \returns encoded PDU or NULL in case of error */
+struct msgb *bssgp2_enc_fc_ms_ack(uint32_t tlli, uint8_t tag)
+{
+	struct msgb *msg = bssgp_msgb_alloc();
+	struct bssgp_normal_hdr *bgph;
+
+	if (!msg)
+		return NULL;
+
+	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
+	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC_ACK;
+
+	msgb_tvlv_put_32be(msg, BSSGP_IE_TLLI, tlli);
+	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);
+
+	return msg;
+}
diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map
index e605d27..f8ad901 100644
--- a/src/gb/libosmogb.map
+++ b/src/gb/libosmogb.map
@@ -47,12 +47,18 @@
 
 bssgp2_nsi_tx_ptp;
 bssgp2_nsi_tx_sig;
+bssgp2_dec_fc_bvc;
+bssgp2_dec_fc_ms;
 bssgp2_enc_bvc_block;
 bssgp2_enc_bvc_block_ack;
 bssgp2_enc_bvc_unblock;
 bssgp2_enc_bvc_unblock_ack;
 bssgp2_enc_bvc_reset;
 bssgp2_enc_bvc_reset_ack;
+bssgp2_enc_fc_bvc;
+bssgp2_enc_fc_bvc_ack;
+bssgp2_enc_fc_ms;
+bssgp2_enc_fc_ms_ack;
 bssgp2_enc_status;
 
 bssgp_bvc_fsm_alloc_sig_bss;

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/21610
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I9c89bb1c03550930c07aad7ff8f67129ee7a6320
Gerrit-Change-Number: 21610
Gerrit-PatchSet: 3
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201210/bc636b16/attachment.htm>


More information about the gerrit-log mailing list