pespin submitted this change.
gmm: Initial implementation of rx GMM Information msg
Basic implementation of gprs_gmm_decode_network_name() was cherry-picked
from osmocom-bb 2dfa84e73dca455900e6522f61f5c610077783b7
decode_network_name().
Change-Id: I9b81f8f9113a95cc75666dac5ff9e315d0845fcb
---
M include/osmocom/gprs/gmm/gmm_private.h
M src/gmm/gmm.c
M src/gmm/misc.c
3 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/include/osmocom/gprs/gmm/gmm_private.h b/include/osmocom/gprs/gmm/gmm_private.h
index df3f496..48068d9 100644
--- a/include/osmocom/gprs/gmm/gmm_private.h
+++ b/include/osmocom/gprs/gmm/gmm_private.h
@@ -88,6 +88,10 @@
unsigned long t3314_assigned_sec; /* value assigned by the network */
struct osmo_timer_list t3312; /* periodic RAU, in seconds */
unsigned long t3312_assigned_sec; /* value assigned by the network */
+
+ /* network name */
+ char name_long[32];
+ char name_short[32];
};
/* gmm_prim.c: */
@@ -137,6 +141,7 @@
/* misc.c */
int gprs_gmm_gprs_tmr_to_secs(uint8_t gprs_tmr);
uint8_t gprs_gmm_secs_to_gprs_tmr_floor(int secs);
+int gprs_gmm_decode_network_name(char *name, int name_len, const uint8_t *lv);
#define LOGGMME(gmme, level, fmt, args...) \
LOGGMM(level, "GMME(IMSI-%s:PTMSI-%08x:TLLI-%08x) " fmt, \
diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c
index f4fdd6c..a99fe57 100644
--- a/src/gmm/gmm.c
+++ b/src/gmm/gmm.c
@@ -1240,6 +1240,33 @@
return 0;
}
+/* Rx GMM Information, 9.4.19 */
+static int gprs_gmm_rx_information(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
+{
+ struct tlv_parsed tp;
+ int rc;
+
+ if (len <= sizeof(struct gsm48_hdr)) /* no Optional IEs, empty msg */
+ return 0;
+
+ rc = gprs_gmm_tlv_parse(&tp, &gh->data[0],
+ len - sizeof(*gh));
+ if (rc < 0) {
+ LOGGMME(gmme, LOGL_ERROR, "Rx GMM INFORMATION: failed to parse TLVs %d\n", rc);
+ return -EINVAL;
+ }
+
+ if (TLVP_PRESENT(&tp, GSM48_IE_GSM_NAME_FULL))
+ gprs_gmm_decode_network_name(gmme->name_long, sizeof(gmme->name_long),
+ TLVP_VAL(&tp, GSM48_IE_GSM_NAME_FULL)-1);
+
+ if (TLVP_PRESENT(&tp, GSM48_IE_GSM_NAME_SHORT))
+ gprs_gmm_decode_network_name(gmme->name_short, sizeof(gmme->name_short),
+ TLVP_VAL(&tp, GSM48_IE_GSM_NAME_SHORT)-1);
+
+ return 0;
+}
+
/* Rx GPRS Mobility Management. */
int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
{
@@ -1270,6 +1297,9 @@
case GSM48_MT_GMM_STATUS:
rc = gprs_gmm_rx_status(gmme, gh, len);
break;
+ case GSM48_MT_GMM_INFO:
+ rc = gprs_gmm_rx_information(gmme, gh, len);
+ break;
default:
LOGGMME(gmme, LOGL_ERROR,
"Rx GMM message not implemented! type=%u len=%u\n",
diff --git a/src/gmm/misc.c b/src/gmm/misc.c
index c54bf3c..18ed8c6 100644
--- a/src/gmm/misc.c
+++ b/src/gmm/misc.c
@@ -20,6 +20,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gprs/gmm/gmm.h>
@@ -79,3 +80,29 @@
return GPRS_TMR_6MINUTE | GPRS_TMR_FACT_MASK;
}
+
+
+/* Decode TS 24.008 10.5.3.5a "Network name".
+ * FIXME: This should be improved & moved to libosmocore at some point, since it is also used in CS MM.
+ */
+int gprs_gmm_decode_network_name(char *name, int name_len, const uint8_t *lv)
+{
+ uint8_t in_len = lv[0];
+ int length, padding;
+
+ name[0] = '\0';
+ if (in_len < 1)
+ return -EINVAL;
+
+ /* must be CB encoded */
+ if ((lv[1] & 0x70) != 0x00)
+ return -ENOTSUP;
+
+ padding = lv[1] & 0x03;
+ length = ((in_len - 1) * 8 - padding) / 7;
+ if (length <= 0)
+ return 0;
+ gsm_7bit_decode_n(name, name_len, lv + 2, length);
+
+ return length;
+}
To view, visit change 33002. To unsubscribe, or for help writing mail filters, visit settings.