<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/22046">View Change</a></p><div style="white-space:pre-wrap">Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gprs_bssgp: add utilities to send and parse BSSGP rim PDUs<br><br>At the moment libosmogb offers no convinient way to send RIM PDUs. Also<br>parsing an incoming RIM messages into destination, source routing<br>info and RIM container is not available.<br><br>Change-Id: I18134fd9938040d2facb6beee3732628b167ce8c<br>Related: SYS#5103<br>---<br>M include/osmocom/gprs/gprs_bssgp.h<br>M include/osmocom/gprs/gprs_bssgp_rim.h<br>M src/gb/gprs_bssgp.c<br>M src/gb/gprs_bssgp_rim.c<br>M src/gb/gprs_bssgp_util.c<br>M src/gb/libosmogb.map<br>6 files changed, 269 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gprs/gprs_bssgp.h b/include/osmocom/gprs/gprs_bssgp.h</span><br><span>index 9255661..a7b363b 100644</span><br><span>--- a/include/osmocom/gprs/gprs_bssgp.h</span><br><span>+++ b/include/osmocom/gprs/gprs_bssgp.h</span><br><span>@@ -11,6 +11,7 @@</span><br><span> </span><br><span> #include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span> #include <osmocom/gprs/protocol/gsm_24_301.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_bssgp_rim.h></span><br><span> </span><br><span> /* gprs_bssgp_util.c */</span><br><span> </span><br><span>@@ -41,6 +42,39 @@</span><br><span> /* Chapter 10.4.14: Status */</span><br><span> int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_information_pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_rim_routing_info routing_info_dest;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_rim_routing_info routing_info_src;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Encoded variant of the RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t rim_cont_iei;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int rim_cont_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Decoded variant of the RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool decoded_present;</span><br><span style="color: hsl(120, 100%, 40%);">+ union {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_inf_req_rim_cont req_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_inf_rim_cont rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_inf_ack_rim_cont ack_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_inf_err_rim_cont err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_inf_app_err_rim_cont app_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ } decoded;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* When receiving a PDU from BSSGP the encoded variant of the RIM</span><br><span style="color: hsl(120, 100%, 40%);">+ * container will always be present. The decoded variant will be</span><br><span style="color: hsl(120, 100%, 40%);">+ * present in addition whenever BSSGP was able to decode the container.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * When sending a PDU to BSSGP, then the decoded variant is used when</span><br><span style="color: hsl(120, 100%, 40%);">+ * it is available. The encoded variant (if present) will be ignored</span><br><span style="color: hsl(120, 100%, 40%);">+ * then. */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum bssgp_prim {</span><br><span> PRIM_BSSGP_DL_UD,</span><br><span> PRIM_BSSGP_UL_UD,</span><br><span>@@ -75,6 +109,7 @@</span><br><span> struct {</span><br><span> uint8_t suspend_ref;</span><br><span> } resume;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_ran_information_pdu rim_pdu;</span><br><span> } u;</span><br><span> };</span><br><span> </span><br><span>diff --git a/include/osmocom/gprs/gprs_bssgp_rim.h b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>index 7f3a0e4..7e9efcd 100644</span><br><span>--- a/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>+++ b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>@@ -54,6 +54,10 @@</span><br><span> };</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* The encoded result of the rim routing information is, depending on the</span><br><span style="color: hsl(120, 100%, 40%);">+ * address type (discr) of variable length. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BSSGP_RIM_ROUTING_INFO_MAXLEN 14</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int bssgp_parse_rim_ri(struct bssgp_rim_routing_info *ri, const uint8_t *buf, unsigned int len);</span><br><span> int bssgp_create_rim_ri(uint8_t *buf, const struct bssgp_rim_routing_info *ri);</span><br><span> </span><br><span>diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c</span><br><span>index 4551427..6fdacce 100644</span><br><span>--- a/src/gb/gprs_bssgp.c</span><br><span>+++ b/src/gb/gprs_bssgp.c</span><br><span>@@ -675,6 +675,8 @@</span><br><span> nmp.nsei = nsei;</span><br><span> nmp.bvci = bvci;</span><br><span> nmp.tp = tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bssgp_parse_rim_pdu(&nmp.u.rim_pdu, msg) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);</span><br><span> osmo_prim_init(&nmp.oph, SAP_BSSGP_RIM, prim, PRIM_OP_INDICATION, msg);</span><br><span> bssgp_prim_cb(&nmp.oph, NULL);</span><br><span> </span><br><span>@@ -1111,7 +1113,7 @@</span><br><span> case BSSGP_PDUT_RAN_INFO_ACK:</span><br><span> case BSSGP_PDUT_RAN_INFO_ERROR:</span><br><span> case BSSGP_PDUT_RAN_INFO_APP_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">- bssgp_rx_rim(msg, tp, bvci);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_rx_rim(msg, tp, bvci);</span><br><span> break;</span><br><span> </span><br><span> /* those only exist in the SGSN -> BSS direction */</span><br><span>diff --git a/src/gb/gprs_bssgp_rim.c b/src/gb/gprs_bssgp_rim.c</span><br><span>index 0dc6d21..7094f5f 100644</span><br><span>--- a/src/gb/gprs_bssgp_rim.c</span><br><span>+++ b/src/gb/gprs_bssgp_rim.c</span><br><span>@@ -96,6 +96,7 @@</span><br><span> {</span><br><span> int rc;</span><br><span> struct gprs_ra_id raid_temp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int len;</span><br><span> </span><br><span> buf[0] = ri->discr & 0x0f;</span><br><span> buf++;</span><br><span>@@ -105,11 +106,13 @@</span><br><span> rc = bssgp_create_cell_id(buf, &ri->geran.raid, ri->geran.cid);</span><br><span> if (rc < 0)</span><br><span> return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- return rc + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ len = rc + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case BSSGP_RIM_ROUTING_INFO_UTRAN:</span><br><span> gsm48_encode_ra((struct gsm48_ra_id *)buf, &ri->utran.raid);</span><br><span> osmo_store16be(ri->utran.rncid, buf + 6);</span><br><span style="color: hsl(0, 100%, 40%);">- return 9;</span><br><span style="color: hsl(120, 100%, 40%);">+ len = 9;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> case BSSGP_RIM_ROUTING_INFO_EUTRAN:</span><br><span> /* Note: 3GPP TS 24.301 Figure 9.9.3.32.1 and 3GPP TS 24.008</span><br><span> * Figure 10.5.130 specify MCC/MNC encoding in the same way,</span><br><span>@@ -126,10 +129,14 @@</span><br><span> sizeof(ri->eutran.global_enb_id));</span><br><span> memcpy(buf + 5, ri->eutran.global_enb_id,</span><br><span> ri->eutran.global_enb_id_len);</span><br><span style="color: hsl(0, 100%, 40%);">- return ri->eutran.global_enb_id_len + 6;</span><br><span style="color: hsl(120, 100%, 40%);">+ len = ri->eutran.global_enb_id_len + 6;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> default:</span><br><span> return -EINVAL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(len <= BSSGP_RIM_ROUTING_INFO_MAXLEN);</span><br><span style="color: hsl(120, 100%, 40%);">+ return len;</span><br><span> }</span><br><span> </span><br><span> /*! Decode a RAN Information Request Application Container for NACC (3GPP TS 48.018, section 11.3.63.1.1).</span><br><span>diff --git a/src/gb/gprs_bssgp_util.c b/src/gb/gprs_bssgp_util.c</span><br><span>index 92896c1..d93c9df 100644</span><br><span>--- a/src/gb/gprs_bssgp_util.c</span><br><span>+++ b/src/gb/gprs_bssgp_util.c</span><br><span>@@ -588,3 +588,218 @@</span><br><span> </span><br><span> return bssgp_ns_send(bssgp_ns_send_data, msg);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Encode RIM PDU into mesage buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = bssgp_encode_rim_pdu(pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+ "BSSGP RIM (NSEI=%u) unable to encode BSSGP RIM PDU\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_nsei(msg) = nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_bvci(msg) = 0; /* Signalling */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ DEBUGP(DLBSSGP, "BSSGP BVCI=0 Tx RIM-PDU:%s\n", bssgp_pdu_str(bgph->pdu_type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return bssgp_ns_send(bssgp_ns_send_data, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Parse a given message buffer into a rim-pdu struct */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tlv_parsed tp[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ int data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t nsei = msgb_nsei(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(pdu, 0, sizeof(*pdu));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ data_len = msgb_bssgp_len(msg) - sizeof(*bgph);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data_len < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, tp, ARRAY_SIZE(tp), bgph->pdu_type, bgph->data, data_len, 0, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ DLBSSGP, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(&tp[0], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_parse_rim_ri(&pdu->routing_info_dest, TLVP_VAL(&tp[0], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+ TLVP_LEN(&tp[0], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(&tp[1], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_parse_rim_ri(&pdu->routing_info_src, TLVP_VAL(&tp[1], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+ TLVP_LEN(&tp[1], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Source Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_REQ_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_iei = BSSGP_IE_RI_REQ_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_iei = BSSGP_IE_RI_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_APP_ERROR_RIM_CONT))</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_iei = BSSGP_IE_RI_APP_ERROR_RIM_CONT;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ACK_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_iei = BSSGP_IE_RI_ACK_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ERROR_RIM_COINTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_iei = BSSGP_IE_RI_ERROR_RIM_COINTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing or wrong RIM Container IE\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont = TLVP_VAL(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_len = TLVP_LEN(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Make sure the rim container field is not empty */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pdu->rim_cont_len < 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pdu->rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: It is not an error if we fail to parse the RIM container,</span><br><span style="color: hsl(120, 100%, 40%);">+ * since there are applications where parsing the RIM container</span><br><span style="color: hsl(120, 100%, 40%);">+ * is not necessary (routing). It is up to the API user to check</span><br><span style="color: hsl(120, 100%, 40%);">+ * the results. */</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_dec_ran_inf_req_rim_cont(&pdu->decoded.req_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_dec_ran_inf_rim_cont(&pdu->decoded.rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_dec_ran_inf_app_err_rim_cont(&pdu->decoded.app_err_rim_cont, pdu->rim_cont,</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_dec_ran_inf_ack_rim_cont(&pdu->decoded.ack_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_dec_ran_inf_err_rim_cont(&pdu->decoded.err_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) cannot parse unknown RIM container.\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) unable to parse RIM container.\n", nsei);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->decoded_present = true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Encode a given rim-pdu struct into a message buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg = bssgp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t rim_ri_buf[BSSGP_RIM_ROUTING_INFO_MAXLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *rim_cont_buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph = (struct bssgp_normal_hdr *)msgb_put(msg, sizeof(*bgph));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set PDU type based on RIM container type */</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph->pdu_type = BSSGP_PDUT_RAN_INFO_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph->pdu_type = BSSGP_PDUT_RAN_INFO;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph->pdu_type = BSSGP_PDUT_RAN_INFO_APP_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The caller must correctly specify the container type! */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Put RIM routing information */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_dest);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_src);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Put RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pdu->decoded_present) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont_buf = talloc_zero_size(msg, msg->data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rim_cont_buf)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_req_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.req_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_app_err_rim_cont(rim_cont_buf, msg->data_len,</span><br><span style="color: hsl(120, 100%, 40%);">+ &pdu->decoded.app_err_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_ack_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.ack_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_err_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.err_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* The API user must set the iei properly! */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tvlv_put(msg, pdu->rim_cont_iei, rc, rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Make sure the RIM container is actually present. */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(pdu->rim_cont_iei != 0 && pdu->rim_cont_len > 0 && pdu->rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tvlv_put(msg, pdu->rim_cont_iei, pdu->rim_cont_len, pdu->rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+error:</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map</span><br><span>index b012184..763ddc6 100644</span><br><span>--- a/src/gb/libosmogb.map</span><br><span>+++ b/src/gb/libosmogb.map</span><br><span>@@ -30,6 +30,7 @@</span><br><span> bssgp_msgb_tlli_put;</span><br><span> bssgp_msgb_ra_put;</span><br><span> bssgp_parse_cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_parse_rim_pdu;</span><br><span> bssgp_parse_rim_ri;</span><br><span> bssgp_set_bssgp_callback;</span><br><span> bssgp_tx_bvc_block;</span><br><span>@@ -48,6 +49,7 @@</span><br><span> bssgp_tx_resume;</span><br><span> bssgp_tx_resume_ack;</span><br><span> bssgp_tx_resume_nack;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_tx_rim;</span><br><span> bssgp_tx_simple_bvci;</span><br><span> bssgp_tx_status;</span><br><span> bssgp_tx_suspend;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/22046">change 22046</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/22046"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I18134fd9938040d2facb6beee3732628b167ce8c </div>
<div style="display:none"> Gerrit-Change-Number: 22046 </div>
<div style="display:none"> Gerrit-PatchSet: 9 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>