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
This commit is contained in:
parent
770ed7fc24
commit
1576144542
|
@ -88,6 +88,10 @@ struct gprs_gmm_entity {
|
|||
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 @@ int gprs_gmm_submit_llgmm_assing_req(const struct gprs_gmm_entity *gmme);
|
|||
/* 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, \
|
||||
|
|
|
@ -1240,6 +1240,33 @@ static int gprs_gmm_rx_status(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh
|
|||
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 @@ int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int
|
|||
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",
|
||||
|
|
|
@ -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 @@ uint8_t gprs_gmm_secs_to_gprs_tmr_floor(int secs)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue