gmm: Implement periodic RAU procedure
Related: OS#5501 Change-Id: Ie7cba8a2fe3b97bebc558c957cc1bcbe3cc81dbc
This commit is contained in:
parent
72ea2cf2fc
commit
5d8283f31b
|
@ -5,6 +5,20 @@
|
||||||
|
|
||||||
struct gprs_gmm_entity;
|
struct gprs_gmm_entity;
|
||||||
|
|
||||||
|
/* Update type 10.5.5.18 */
|
||||||
|
enum gprs_gmm_upd_type {
|
||||||
|
GPRS_GMM_UPD_TYPE_RA = 0,
|
||||||
|
GPRS_GMM_UPD_TYPE_COMBINED_RA_LA = 1,
|
||||||
|
GPRS_GMM_UPD_TYPE_COMBINED_RA_LA_IMSI = 2,
|
||||||
|
GPRS_GMM_UPD_TYPE_PERIODIC = 3,
|
||||||
|
/* others: reserved */
|
||||||
|
};
|
||||||
|
extern const struct value_string gprs_gmm_upd_type_names[];
|
||||||
|
static inline const char *gprs_gmm_upd_type_name(enum gprs_gmm_upd_type val)
|
||||||
|
{
|
||||||
|
return get_value_string(gprs_gmm_upd_type_names, val);
|
||||||
|
}
|
||||||
|
|
||||||
/* 3GPP TS 24.008 § 4.1.3.1 GMM states in the MS */
|
/* 3GPP TS 24.008 § 4.1.3.1 GMM states in the MS */
|
||||||
enum gprs_gmm_ms_fsm_states {
|
enum gprs_gmm_ms_fsm_states {
|
||||||
GPRS_GMM_MS_ST_NULL, /* 4.1.3.1.1.1 */
|
GPRS_GMM_MS_ST_NULL, /* 4.1.3.1.1.1 */
|
||||||
|
@ -58,12 +72,20 @@ struct gprs_gmm_ms_fsm_detach_ctx {
|
||||||
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type;
|
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Info about last initiated RAU: */
|
||||||
|
struct gprs_gmm_ms_fsm_rau_ctx {
|
||||||
|
enum gprs_gmm_upd_type type;
|
||||||
|
/* Retransmission of RAU REQUEST (4.7.5.1.5) */
|
||||||
|
uint8_t req_attempts;
|
||||||
|
};
|
||||||
|
|
||||||
struct gprs_gmm_ms_fsm_ctx {
|
struct gprs_gmm_ms_fsm_ctx {
|
||||||
struct osmo_fsm_inst *fi;
|
struct osmo_fsm_inst *fi;
|
||||||
struct gprs_gmm_entity *gmme;
|
struct gprs_gmm_entity *gmme;
|
||||||
|
|
||||||
struct gprs_gmm_ms_fsm_attach_ctx attach;
|
struct gprs_gmm_ms_fsm_attach_ctx attach;
|
||||||
struct gprs_gmm_ms_fsm_detach_ctx detach;
|
struct gprs_gmm_ms_fsm_detach_ctx detach;
|
||||||
|
struct gprs_gmm_ms_fsm_rau_ctx rau;
|
||||||
};
|
};
|
||||||
|
|
||||||
int gprs_gmm_ms_fsm_init(void);
|
int gprs_gmm_ms_fsm_init(void);
|
||||||
|
@ -81,3 +103,5 @@ int gprs_gmm_ms_fsm_ctx_request_detach(struct gprs_gmm_ms_fsm_ctx *ctx,
|
||||||
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
||||||
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type);
|
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type);
|
||||||
|
|
||||||
|
int gprs_gmm_ms_fsm_ctx_request_rau(struct gprs_gmm_ms_fsm_ctx *ctx,
|
||||||
|
enum gprs_gmm_upd_type rau_type);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <osmocom/gsm/tlv.h>
|
#include <osmocom/gsm/tlv.h>
|
||||||
|
|
||||||
struct gprs_gmm_entity;
|
struct gprs_gmm_entity;
|
||||||
|
enum gprs_gmm_upd_type;
|
||||||
|
|
||||||
#define GPRS_GMM_ALLOC_SIZE 2048
|
#define GPRS_GMM_ALLOC_SIZE 2048
|
||||||
#define GPRS_GMM_ALLOC_HEADROOM 256
|
#define GPRS_GMM_ALLOC_HEADROOM 256
|
||||||
|
@ -36,3 +37,9 @@ int gprs_gmm_build_detach_req(struct gprs_gmm_entity *gmme,
|
||||||
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
||||||
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type,
|
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type,
|
||||||
struct msgb *msg);
|
struct msgb *msg);
|
||||||
|
|
||||||
|
int gprs_gmm_build_rau_req(struct gprs_gmm_entity *gmme,
|
||||||
|
enum gprs_gmm_upd_type rau_type,
|
||||||
|
struct msgb *msg);
|
||||||
|
|
||||||
|
int gprs_gmm_build_rau_compl(struct gprs_gmm_entity *gmme, struct msgb *msg);
|
||||||
|
|
|
@ -126,6 +126,7 @@ int gprs_gmm_tx_att_req(struct gprs_gmm_entity *gmme,
|
||||||
int gprs_gmm_tx_detach_req(struct gprs_gmm_entity *gmme,
|
int gprs_gmm_tx_detach_req(struct gprs_gmm_entity *gmme,
|
||||||
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
enum osmo_gprs_gmm_detach_ms_type detach_type,
|
||||||
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type);
|
enum osmo_gprs_gmm_detach_poweroff_type poweroff_type);
|
||||||
|
int gprs_gmm_tx_rau_req(struct gprs_gmm_entity *gmme, enum gprs_gmm_upd_type rau_type);
|
||||||
int gprs_gmm_tx_ciph_auth_resp(const struct gprs_gmm_entity *gmme, const uint8_t *sres);
|
int gprs_gmm_tx_ciph_auth_resp(const struct gprs_gmm_entity *gmme, const uint8_t *sres);
|
||||||
|
|
||||||
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause);
|
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause);
|
||||||
|
|
213
src/gmm/gmm.c
213
src/gmm/gmm.c
|
@ -78,6 +78,14 @@ static struct osmo_tdef T_defs_gmm[] = {
|
||||||
{ 0 } /* empty item at the end */
|
{ 0 } /* empty item at the end */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct value_string gprs_gmm_upd_type_names[] = {
|
||||||
|
{ GPRS_GMM_UPD_TYPE_RA, "RA updating" },
|
||||||
|
{ GPRS_GMM_UPD_TYPE_COMBINED_RA_LA, "Combined RA/LA updating" },
|
||||||
|
{ GPRS_GMM_UPD_TYPE_COMBINED_RA_LA_IMSI, "Combined RA/LA updating with IMSI attac" },
|
||||||
|
{ GPRS_GMM_UPD_TYPE_PERIODIC, "Periodic updating" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static void t3314_ready_timer_cb(void *data);
|
static void t3314_ready_timer_cb(void *data);
|
||||||
static void t3312_periodic_rau_timer_cb(void *data);
|
static void t3312_periodic_rau_timer_cb(void *data);
|
||||||
|
|
||||||
|
@ -296,7 +304,7 @@ void gprs_gmm_gmme_ready_timer_start(struct gprs_gmm_entity *gmme)
|
||||||
{
|
{
|
||||||
if (gmme->t3314_assigned_sec == 0)
|
if (gmme->t3314_assigned_sec == 0)
|
||||||
return;
|
return;
|
||||||
LOGGMME(gmme, LOGL_INFO, "READY timer started\n");
|
LOGGMME(gmme, LOGL_INFO, "READY timer started (expires in %lu seconds)\n", gmme->t3314_assigned_sec);
|
||||||
osmo_timer_schedule(&gmme->t3314, gmme->t3314_assigned_sec, 0);
|
osmo_timer_schedule(&gmme->t3314, gmme->t3314_assigned_sec, 0);
|
||||||
|
|
||||||
/* "Timer T3312 is stopped and shall be set to its initial value
|
/* "Timer T3312 is stopped and shall be set to its initial value
|
||||||
|
@ -341,14 +349,11 @@ static void t3314_ready_timer_cb(void *data)
|
||||||
/* T3312 (Periodic RAU) is started: */
|
/* T3312 (Periodic RAU) is started: */
|
||||||
void gprs_gmm_gmme_t3312_start(struct gprs_gmm_entity *gmme)
|
void gprs_gmm_gmme_t3312_start(struct gprs_gmm_entity *gmme)
|
||||||
{
|
{
|
||||||
unsigned long t3312_sec;
|
if (gmme->t3312_assigned_sec == 0)
|
||||||
|
|
||||||
t3312_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3312, OSMO_TDEF_S, -1);
|
|
||||||
if (t3312_sec == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOGGMME(gmme, LOGL_INFO, "T3312 started\n");
|
LOGGMME(gmme, LOGL_INFO, "T3312 started (expires in %lu seconds)\n", gmme->t3312_assigned_sec);
|
||||||
osmo_timer_schedule(&gmme->t3312, t3312_sec, 0);
|
osmo_timer_schedule(&gmme->t3312, gmme->t3312_assigned_sec, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* T3312 (Periodic RAU) is stopped: */
|
/* T3312 (Periodic RAU) is stopped: */
|
||||||
|
@ -380,6 +385,8 @@ static void t3312_periodic_rau_timer_cb(void *data)
|
||||||
* routing area updating procedure when it returns to state
|
* routing area updating procedure when it returns to state
|
||||||
* GMM-REGISTERED.NORMAL-SERVICE."
|
* GMM-REGISTERED.NORMAL-SERVICE."
|
||||||
*/
|
*/
|
||||||
|
gprs_gmm_ms_fsm_ctx_request_rau(&gmme->ms_fsm, GPRS_GMM_UPD_TYPE_PERIODIC);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause)
|
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause)
|
||||||
|
@ -641,6 +648,71 @@ int gprs_gmm_tx_detach_req(struct gprs_gmm_entity *gmme,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tx GMM Routing area update request, 9.4.14 */
|
||||||
|
int gprs_gmm_tx_rau_req(struct gprs_gmm_entity *gmme,
|
||||||
|
enum gprs_gmm_upd_type rau_type)
|
||||||
|
{
|
||||||
|
struct osmo_gprs_llc_prim *llc_prim;
|
||||||
|
int rc;
|
||||||
|
struct msgb *msg;
|
||||||
|
|
||||||
|
LOGGMME(gmme, LOGL_INFO, "Tx GMM RAU REQUEST\n");
|
||||||
|
llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req(
|
||||||
|
gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE);
|
||||||
|
msg = llc_prim->oph.msg;
|
||||||
|
msg->l3h = msg->tail;
|
||||||
|
rc = gprs_gmm_build_rau_req(gmme, rau_type, msg);
|
||||||
|
if (rc < 0) {
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EBADMSG;
|
||||||
|
}
|
||||||
|
llc_prim->ll.l3_pdu = msg->l3h;
|
||||||
|
llc_prim->ll.l3_pdu_len = msgb_l3len(msg);
|
||||||
|
/* TODO:
|
||||||
|
llc_prim->ll.qos_params.*;
|
||||||
|
llc_prim->ll.radio_prio;
|
||||||
|
llc_prim->ll.apply_gea;
|
||||||
|
llc_prim->ll.apply_gia;
|
||||||
|
*/
|
||||||
|
|
||||||
|
rc = gprs_gmm_prim_call_llc_down_cb(llc_prim);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tx GMM Routing area update complete, 9.4.16 */
|
||||||
|
static int gprs_gmm_tx_rau_compl(struct gprs_gmm_entity *gmme)
|
||||||
|
{
|
||||||
|
struct osmo_gprs_llc_prim *llc_prim;
|
||||||
|
int rc;
|
||||||
|
struct msgb *msg;
|
||||||
|
|
||||||
|
LOGGMME(gmme, LOGL_INFO, "Tx GMM RAU COMPL\n");
|
||||||
|
|
||||||
|
llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req(
|
||||||
|
gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE);
|
||||||
|
msg = llc_prim->oph.msg;
|
||||||
|
msg->l3h = msg->tail;
|
||||||
|
rc = gprs_gmm_build_rau_compl(gmme, msg);
|
||||||
|
if (rc < 0) {
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EBADMSG;
|
||||||
|
}
|
||||||
|
llc_prim->ll.l3_pdu = msg->l3h;
|
||||||
|
llc_prim->ll.l3_pdu_len = msgb_l3len(msg);
|
||||||
|
/* TODO:
|
||||||
|
llc_prim->ll.qos_params.*;
|
||||||
|
llc_prim->ll.radio_prio;
|
||||||
|
llc_prim->ll.apply_gea;
|
||||||
|
llc_prim->ll.apply_gia;
|
||||||
|
*/
|
||||||
|
|
||||||
|
rc = gprs_gmm_prim_call_llc_down_cb(llc_prim);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int gprs_gmm_rx_att_ack(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
|
static int gprs_gmm_rx_att_ack(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
|
||||||
{
|
{
|
||||||
struct gsm48_attach_ack *aa;
|
struct gsm48_attach_ack *aa;
|
||||||
|
@ -815,6 +887,130 @@ rejected:
|
||||||
return -EINVAL; /* TODO: what to do on error? */
|
return -EINVAL; /* TODO: what to do on error? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Rx Routing area update accept, 9.4.15 */
|
||||||
|
static int gprs_gmm_rx_rau_acc(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
|
||||||
|
{
|
||||||
|
struct gsm48_ra_upd_ack *raack;
|
||||||
|
struct tlv_parsed tp;
|
||||||
|
int rc;
|
||||||
|
int periodic_rau_sec;
|
||||||
|
|
||||||
|
if (len < sizeof(*gh) + sizeof(*raack)) {
|
||||||
|
LOGGMME(gmme, LOGL_ERROR, "Rx GMM RAU ACCEPT with wrong size %u\n", len);
|
||||||
|
goto rejected;
|
||||||
|
}
|
||||||
|
|
||||||
|
raack = (struct gsm48_ra_upd_ack *)&gh->data[0];
|
||||||
|
LOGGMME(gmme, LOGL_INFO, "Rx GMM RAU ACCEPT upd_result=0x%02x\n", raack->upd_result);
|
||||||
|
|
||||||
|
/* TODO: check raack->upd_result */
|
||||||
|
|
||||||
|
periodic_rau_sec = gprs_gmm_gprs_tmr_to_secs(raack->ra_upd_timer);
|
||||||
|
gmme->t3312_assigned_sec = periodic_rau_sec >= 0 ? periodic_rau_sec : 0;
|
||||||
|
if (gmme->t3312_assigned_sec == 0)
|
||||||
|
gprs_gmm_gmme_t3312_stop(gmme);
|
||||||
|
gsm48_parse_ra(&gmme->ra, (const uint8_t *)&raack->ra_id);
|
||||||
|
|
||||||
|
if (len > sizeof(*gh) + sizeof(*raack)) {
|
||||||
|
rc = gprs_gmm_tlv_parse(&tp, &raack->data[0],
|
||||||
|
len - (sizeof(*gh) + sizeof(*raack)));
|
||||||
|
if (rc < 0) {
|
||||||
|
LOGGMME(gmme, LOGL_ERROR, "Rx GMM RAU ACCEPT: failed to parse TLVs %d\n", rc);
|
||||||
|
goto rejected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10.5.5.8 P-TMSI signature */
|
||||||
|
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_PTMSI_SIG)) {
|
||||||
|
const uint8_t *ptmsi_sig = TLVP_VAL(&tp, GSM48_IE_GMM_PTMSI_SIG);
|
||||||
|
gmme->ptmsi_sig = (ptmsi_sig[0] << 8) | (ptmsi_sig[1] << 4) | ptmsi_sig[2];
|
||||||
|
} else {
|
||||||
|
gmme->ptmsi_sig = GSM_RESERVED_TMSI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10.5.1.4 Allocated P-TMSI */
|
||||||
|
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_ALLOC_PTMSI)) {
|
||||||
|
struct osmo_mobile_identity mi;
|
||||||
|
if (osmo_mobile_identity_decode(&mi, TLVP_VAL(&tp, GSM48_IE_GMM_ALLOC_PTMSI),
|
||||||
|
TLVP_LEN(&tp, GSM48_IE_GMM_ALLOC_PTMSI), false)
|
||||||
|
|| mi.type != GSM_MI_TYPE_TMSI) {
|
||||||
|
LOGGMME(gmme, LOGL_ERROR, "Cannot decode P-TMSI\n");
|
||||||
|
goto rejected;
|
||||||
|
}
|
||||||
|
gmme->old_ptmsi = gmme->ptmsi;
|
||||||
|
gmme->ptmsi = mi.tmsi;
|
||||||
|
/* TS 24.008 4.7.1.4.1:"Upon receipt of the assigned P-TMSI, the MS
|
||||||
|
* shall derive the local TLLI from this P-TMSI and shall use it for
|
||||||
|
* addressing at lower layers": */
|
||||||
|
gmme->old_tlli = gmme->tlli;
|
||||||
|
gmme->tlli = gprs_tmsi2tlli(gmme->ptmsi, TLLI_LOCAL);
|
||||||
|
}
|
||||||
|
/* FIXME! what to do it PTMSI changes? probably need to update other layers... Check GPRS ATTACH ACCEPT func */
|
||||||
|
|
||||||
|
/* 10.5.1.4 MS identity */
|
||||||
|
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_IMEISV)) {
|
||||||
|
struct osmo_mobile_identity mi;
|
||||||
|
if (osmo_mobile_identity_decode(&mi, TLVP_VAL(&tp, GSM48_IE_GMM_IMEISV),
|
||||||
|
TLVP_LEN(&tp, GSM48_IE_GMM_IMEISV), false)
|
||||||
|
|| mi.type != GSM_MI_TYPE_IMEISV) {
|
||||||
|
LOGGMME(gmme, LOGL_ERROR, "Cannot decode IMEISV\n");
|
||||||
|
goto rejected;
|
||||||
|
}
|
||||||
|
/* TODO: */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10.5.5.11 List of Receive N-PDU Numbers: TODO */
|
||||||
|
|
||||||
|
/* 10.5.7.3 Negotiated READY timer value */
|
||||||
|
if (TLVP_PRESENT(&tp, GSM48_IE_GMM_TIMER_READY)) {
|
||||||
|
int secs = gprs_gmm_gprs_tmr_to_secs(*TLVP_VAL(&tp, GSM48_IE_GMM_TIMER_READY));
|
||||||
|
gmme->t3314_assigned_sec = secs >= 0 ? secs : 0;
|
||||||
|
} else {
|
||||||
|
/* Apply the requested value: */
|
||||||
|
gmme->t3314_assigned_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3314, OSMO_TDEF_S, -1);
|
||||||
|
}
|
||||||
|
/* "If the negotiated READY timer value is set to zero, the READY timer shall be stopped immediately": */
|
||||||
|
if (gmme->t3314_assigned_sec == 0) {
|
||||||
|
gprs_gmm_gmme_ready_timer_stop(gmme);
|
||||||
|
/* "If after a READY timer negotiation the READY timer
|
||||||
|
* value is set to zero, timer T3312 is reset and started
|
||||||
|
* with its initial value." */
|
||||||
|
gprs_gmm_gmme_t3312_start(gmme);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10.5.5.14 GMM cause: TODO */
|
||||||
|
|
||||||
|
/* 10.5.7.4 T3302 value */
|
||||||
|
if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_TIMER_T3302, 1))
|
||||||
|
gmme->t3302 = *TLVP_VAL(&tp, GSM48_IE_GMM_TIMER_T3302);
|
||||||
|
|
||||||
|
/* 10.5.1.13 Equivalent PLMNs: TODO */
|
||||||
|
/* 10.5.7.1 PDP context status: TODO */
|
||||||
|
|
||||||
|
/* TODO: lots more Optional IEs */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Submit LLGMM-ASSIGN-REQ as per TS 24.007 Annex C.1 */
|
||||||
|
rc = gprs_gmm_submit_llgmm_assing_req(gmme);
|
||||||
|
if (rc < 0)
|
||||||
|
goto rejected;
|
||||||
|
|
||||||
|
/* Submit GMMRR-ASSIGN-REQ as per TS 24.007 Annex C.1 */
|
||||||
|
rc = gprs_gmm_submit_gmmrr_assing_req(gmme);
|
||||||
|
if (rc < 0)
|
||||||
|
goto rejected;
|
||||||
|
|
||||||
|
rc = gprs_gmm_tx_rau_compl(gmme);
|
||||||
|
if (rc < 0)
|
||||||
|
goto rejected;
|
||||||
|
|
||||||
|
rc = osmo_fsm_inst_dispatch(gmme->ms_fsm.fi, GPRS_GMM_MS_EV_RAU_ACCEPTED, NULL);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rejected:
|
||||||
|
return -EINVAL; /* TODO: what to do on error? */
|
||||||
|
}
|
||||||
|
|
||||||
/* Rx GMM Identity Request, 9.2.10 */
|
/* Rx GMM Identity Request, 9.2.10 */
|
||||||
static int gprs_gmm_rx_id_req(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
|
static int gprs_gmm_rx_id_req(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len)
|
||||||
{
|
{
|
||||||
|
@ -916,6 +1112,9 @@ int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int
|
||||||
case GSM48_MT_GMM_DETACH_ACK:
|
case GSM48_MT_GMM_DETACH_ACK:
|
||||||
rc = gprs_gmm_rx_detach_accept(gmme, gh, len);
|
rc = gprs_gmm_rx_detach_accept(gmme, gh, len);
|
||||||
break;
|
break;
|
||||||
|
case GSM48_MT_GMM_RA_UPD_ACK:
|
||||||
|
rc = gprs_gmm_rx_rau_acc(gmme, gh, len);
|
||||||
|
break;
|
||||||
case GSM48_MT_GMM_ID_REQ:
|
case GSM48_MT_GMM_ID_REQ:
|
||||||
rc = gprs_gmm_rx_id_req(gmme, gh, len);
|
rc = gprs_gmm_rx_id_req(gmme, gh, len);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -35,7 +35,7 @@ static const struct osmo_tdef_state_timeout gmm_ms_fsm_timeouts[32] = {
|
||||||
[GPRS_GMM_MS_ST_REGISTERED_INITIATED] = { .T = 3310 },
|
[GPRS_GMM_MS_ST_REGISTERED_INITIATED] = { .T = 3310 },
|
||||||
[GPRS_GMM_MS_ST_REGISTERED] = {},
|
[GPRS_GMM_MS_ST_REGISTERED] = {},
|
||||||
[GPRS_GMM_MS_ST_DEREGISTERED_INITIATED] = {},
|
[GPRS_GMM_MS_ST_DEREGISTERED_INITIATED] = {},
|
||||||
[GPRS_GMM_MS_ST_RAU_INITIATED] = {},
|
[GPRS_GMM_MS_ST_RAU_INITIATED] = { .T = 3330 },
|
||||||
[GPRS_GMM_MS_ST_SR_INITIATED] = {},
|
[GPRS_GMM_MS_ST_SR_INITIATED] = {},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,19 @@ static int reinit_attach_proc(struct gprs_gmm_ms_fsm_ctx *ctx)
|
||||||
ctx->attach.with_imsi);
|
ctx->attach.with_imsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int reinit_rau_proc(struct gprs_gmm_ms_fsm_ctx *ctx)
|
||||||
|
{
|
||||||
|
unsigned long val_sec;
|
||||||
|
|
||||||
|
OSMO_ASSERT(ctx->fi->state == GPRS_GMM_MS_ST_RAU_INITIATED);
|
||||||
|
|
||||||
|
/* Rearm T3330 */
|
||||||
|
OSMO_ASSERT(ctx->fi->T == 3330);
|
||||||
|
val_sec = osmo_tdef_get(g_gmm_ctx->T_defs, ctx->fi->T, OSMO_TDEF_S, -1);
|
||||||
|
osmo_timer_schedule(&ctx->fi->timer, val_sec, 0);
|
||||||
|
return gprs_gmm_tx_rau_req(ctx->gmme, ctx->rau.type);
|
||||||
|
}
|
||||||
|
|
||||||
static void st_gmm_ms_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
static void st_gmm_ms_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
{
|
{
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -168,11 +181,24 @@ static void st_gmm_ms_registered_on_enter(struct osmo_fsm_inst *fi, uint32_t pre
|
||||||
|
|
||||||
static void st_gmm_ms_registered(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
static void st_gmm_ms_registered(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
{
|
{
|
||||||
|
struct gprs_gmm_ms_fsm_ctx *ctx = (struct gprs_gmm_ms_fsm_ctx *)fi->priv;
|
||||||
|
struct osmo_gprs_llc_prim *llc_prim_tx;
|
||||||
|
int rc;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case GPRS_GMM_MS_EV_SR_REQUESTED:
|
case GPRS_GMM_MS_EV_SR_REQUESTED:
|
||||||
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
|
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
|
||||||
break;
|
break;
|
||||||
case GPRS_GMM_MS_EV_RAU_REQUESTED:
|
case GPRS_GMM_MS_EV_RAU_REQUESTED:
|
||||||
|
/* TS 24.007 C.15: submit LLGMM-SUSPEND-REQ */
|
||||||
|
llc_prim_tx = osmo_gprs_llc_prim_alloc_llgm_suspend_req(ctx->gmme->tlli);
|
||||||
|
OSMO_ASSERT(llc_prim_tx);
|
||||||
|
rc = gprs_gmm_prim_call_llc_down_cb(llc_prim_tx);
|
||||||
|
/* Transmit RAU Requested to SGSN: */
|
||||||
|
rc = gprs_gmm_tx_rau_req(ctx->gmme,
|
||||||
|
ctx->rau.type);
|
||||||
|
if (rc < 0)
|
||||||
|
return;
|
||||||
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_RAU_INITIATED);
|
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_RAU_INITIATED);
|
||||||
break;
|
break;
|
||||||
case GPRS_GMM_MS_EV_DETACH_REQUESTED:
|
case GPRS_GMM_MS_EV_DETACH_REQUESTED:
|
||||||
|
@ -200,6 +226,9 @@ static void st_gmm_ms_deregistered_initiated(struct osmo_fsm_inst *fi, uint32_t
|
||||||
|
|
||||||
static void st_gmm_ms_rau_initiated(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
static void st_gmm_ms_rau_initiated(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
{
|
{
|
||||||
|
struct gprs_gmm_ms_fsm_ctx *ctx = (struct gprs_gmm_ms_fsm_ctx *)fi->priv;
|
||||||
|
struct osmo_gprs_llc_prim *llc_prim_tx;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case GPRS_GMM_MS_EV_RAU_REJECTED:
|
case GPRS_GMM_MS_EV_RAU_REJECTED:
|
||||||
// causes #13, #15, #25
|
// causes #13, #15, #25
|
||||||
|
@ -208,6 +237,10 @@ static void st_gmm_ms_rau_initiated(struct osmo_fsm_inst *fi, uint32_t event, vo
|
||||||
//mm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED_INITIATED);
|
//mm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_DEREGISTERED_INITIATED);
|
||||||
break;
|
break;
|
||||||
case GPRS_GMM_MS_EV_RAU_ACCEPTED:
|
case GPRS_GMM_MS_EV_RAU_ACCEPTED:
|
||||||
|
/* TS 24.007 C.15: submit LLGM-RESUME-REQ */
|
||||||
|
llc_prim_tx = osmo_gprs_llc_prim_alloc_llgm_resume_req(ctx->gmme->tlli);
|
||||||
|
OSMO_ASSERT(llc_prim_tx);
|
||||||
|
gprs_gmm_prim_call_llc_down_cb(llc_prim_tx);
|
||||||
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
|
gmm_ms_fsm_state_chg(fi, GPRS_GMM_MS_ST_REGISTERED);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -347,7 +380,7 @@ int gmm_ms_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
|
|
||||||
switch (fi->T) {
|
switch (fi->T) {
|
||||||
case 3310:
|
case 3310:
|
||||||
/* TS 23.008 clause 4.7.3.1.5 c) */
|
/* TS 24.008 clause 4.7.3.1.5 c) */
|
||||||
ctx->attach.req_attempts++;
|
ctx->attach.req_attempts++;
|
||||||
LOGPFSML(ctx->fi, LOGL_INFO, "T3310 timeout attempts=%u\n", ctx->attach.req_attempts);
|
LOGPFSML(ctx->fi, LOGL_INFO, "T3310 timeout attempts=%u\n", ctx->attach.req_attempts);
|
||||||
OSMO_ASSERT(fi->state == GPRS_GMM_MS_ST_REGISTERED_INITIATED);
|
OSMO_ASSERT(fi->state == GPRS_GMM_MS_ST_REGISTERED_INITIATED);
|
||||||
|
@ -360,6 +393,20 @@ int gmm_ms_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
}
|
}
|
||||||
reinit_attach_proc(ctx);
|
reinit_attach_proc(ctx);
|
||||||
break;
|
break;
|
||||||
|
case 3330:
|
||||||
|
/* TS 24.008 clause 4.7.5.1.5 c) */
|
||||||
|
ctx->rau.req_attempts++;
|
||||||
|
LOGPFSML(ctx->fi, LOGL_INFO, "T3330 timeout attempts=%u\n", ctx->rau.req_attempts);
|
||||||
|
OSMO_ASSERT(fi->state == GPRS_GMM_MS_ST_RAU_INITIATED);
|
||||||
|
if (ctx->rau.req_attempts == 4) {
|
||||||
|
/* "On the fifth expiry of timer T3330, the MS shall
|
||||||
|
* abort the GPRS attach procedure" */
|
||||||
|
LOGPFSML(ctx->fi, LOGL_NOTICE, "GPRS RAU procedure failure (T3330 timeout attempts=%u)\n", ctx->rau.req_attempts);
|
||||||
|
osmo_fsm_inst_dispatch(ctx->fi, GPRS_GMM_MS_EV_LOW_LVL_FAIL, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
reinit_rau_proc(ctx);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
OSMO_ASSERT(0);
|
OSMO_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
@ -449,3 +496,14 @@ int gprs_gmm_ms_fsm_ctx_request_detach(struct gprs_gmm_ms_fsm_ctx *ctx,
|
||||||
rc = gprs_gmm_tx_detach_req(ctx->gmme, detach_type, poweroff_type);
|
rc = gprs_gmm_tx_detach_req(ctx->gmme, detach_type, poweroff_type);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gprs_gmm_ms_fsm_ctx_request_rau(struct gprs_gmm_ms_fsm_ctx *ctx,
|
||||||
|
enum gprs_gmm_upd_type rau_type)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
ctx->rau.type = rau_type;
|
||||||
|
rc = osmo_fsm_inst_dispatch(ctx->fi, GPRS_GMM_MS_EV_RAU_REQUESTED, NULL);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
|
@ -151,6 +151,26 @@ const struct tlv_definition gprs_gmm_att_tlvdef = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int encode_ms_net_cap(struct gprs_gmm_entity *gmme, struct msgb *msg)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
uint8_t *l; /* len */
|
||||||
|
struct bitvec bv = {
|
||||||
|
.data = msg->tail,
|
||||||
|
.data_len = GSM_MACBLOCK_LEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
msgb_put_u8(msg, GSM48_IE_GMM_MS_NET_CAPA);
|
||||||
|
|
||||||
|
l = msgb_put(msg, 1); /* len */
|
||||||
|
|
||||||
|
/* TODO: we hardcode a MS Net Cap for now. We may want to pass it from the app at some point: */
|
||||||
|
rc = bitvec_unhex(&bv, "e5e0");
|
||||||
|
*l = OSMO_BYTES_FOR_BITS(bv.cur_bit);
|
||||||
|
msgb_put(msg, *l);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int encode_ms_ra_acc_cap(struct gprs_gmm_entity *gmme, struct msgb *msg)
|
static int encode_ms_ra_acc_cap(struct gprs_gmm_entity *gmme, struct msgb *msg)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -264,6 +284,68 @@ int gprs_gmm_build_attach_compl(struct gprs_gmm_entity *gmme, struct msgb *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Chapter 9.4.14: Routing area update request */
|
||||||
|
int gprs_gmm_build_rau_req(struct gprs_gmm_entity *gmme,
|
||||||
|
enum gprs_gmm_upd_type rau_type,
|
||||||
|
struct msgb *msg)
|
||||||
|
{
|
||||||
|
struct gsm48_hdr *gh;
|
||||||
|
uint8_t byte, cksn;
|
||||||
|
int rc;
|
||||||
|
struct gsm48_ra_id *raid_enc;
|
||||||
|
unsigned long t3314_sec;
|
||||||
|
uint8_t ptmsi_type_native = 1; /* Table 10.5.5.29.1 */
|
||||||
|
|
||||||
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||||
|
gh->proto_discr = GSM48_PDISC_MM_GPRS;
|
||||||
|
gh->msg_type = GSM48_MT_GMM_RA_UPD_REQ;
|
||||||
|
|
||||||
|
/* 10.5.5.18 Update type */
|
||||||
|
cksn = gmme->auth_ciph.req.key_seq;
|
||||||
|
byte = (cksn << 4) | (((uint8_t)rau_type) & 0x07);
|
||||||
|
msgb_put_u8(msg, byte);
|
||||||
|
|
||||||
|
/* Old routing area identification 0.5.5.15 */
|
||||||
|
raid_enc = (struct gsm48_ra_id *)msgb_put(msg, sizeof(struct gsm48_ra_id));
|
||||||
|
gsm48_encode_ra(raid_enc, &gmme->ra);
|
||||||
|
|
||||||
|
/* MS Radio Access capability 10.5.5.12a */
|
||||||
|
rc = encode_ms_ra_acc_cap(gmme, msg);
|
||||||
|
if (rc < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* 10.5.5.8 Old P-TMSI signature: */
|
||||||
|
if (gmme->ptmsi_sig != GSM_RESERVED_TMSI) {
|
||||||
|
uint8_t ptmsi_sig[3] = { gmme->ptmsi_sig >> 16, gmme->ptmsi_sig >> 8, gmme->ptmsi_sig };
|
||||||
|
msgb_tv_fixed_put(msg, GSM48_IE_GMM_PTMSI_SIG, sizeof(ptmsi_sig), ptmsi_sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 10.5.7.3 Requested READY timer value */
|
||||||
|
t3314_sec = osmo_tdef_get(g_gmm_ctx->T_defs, 3314, OSMO_TDEF_S, -1);
|
||||||
|
msgb_tv_put(msg, GSM48_IE_GMM_TIMER_READY, gprs_gmm_secs_to_gprs_tmr_floor(t3314_sec));
|
||||||
|
|
||||||
|
/* DRX parameter 10.5.5.6 */
|
||||||
|
memcpy(msgb_put(msg, sizeof(drx_param_def)),
|
||||||
|
&drx_param_def,
|
||||||
|
sizeof(drx_param_def));
|
||||||
|
|
||||||
|
/* 9.4.14.6 MS network capability */
|
||||||
|
rc = encode_ms_net_cap(gmme, msg);
|
||||||
|
if (rc < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* 9.4.14.7 PDP context status */
|
||||||
|
/* TODO: implement. Table 9.4.14/3GPP TS 24.00 states it is optional (O) but 9.4.14.7 states:
|
||||||
|
* "This IE shall be included by the MS." */
|
||||||
|
|
||||||
|
/* 9.4.14.17 P-TMSI type */
|
||||||
|
/* Table 9.4.14/3GPP TS 24.00 states it is optional (O) but 9.4.14.17 states:
|
||||||
|
* "This IE shall be included by the MS." */
|
||||||
|
msgb_v_put(msg, (GSM48_IE_GMM_PTMSI_TYPE << 4) | (ptmsi_type_native & 0x01));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* 9.2.11 Identity response */
|
/* 9.2.11 Identity response */
|
||||||
int gprs_gmm_build_identity_resp(struct gprs_gmm_entity *gmme,
|
int gprs_gmm_build_identity_resp(struct gprs_gmm_entity *gmme,
|
||||||
uint8_t mi_type,
|
uint8_t mi_type,
|
||||||
|
@ -394,3 +476,15 @@ int gprs_gmm_build_detach_req(struct gprs_gmm_entity *gmme,
|
||||||
/* TODO: optional fields: P-TMSI signature 10.5.5.8a */
|
/* TODO: optional fields: P-TMSI signature 10.5.5.8a */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int gprs_gmm_build_rau_compl(struct gprs_gmm_entity *gmme, struct msgb *msg)
|
||||||
|
{
|
||||||
|
struct gsm48_hdr *gh;
|
||||||
|
|
||||||
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||||
|
gh->proto_discr = GSM48_PDISC_MM_GPRS;
|
||||||
|
gh->msg_type = GSM48_MT_GMM_RA_UPD_COMPL;
|
||||||
|
|
||||||
|
/* TODO: Add optional IEs */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -38,10 +38,13 @@ gmm_misc_test_LDFLAGS = \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# libosmo-gprs-llc.a is used below to access non-exported private symbols used in the test:
|
# libosmo-gprs-llc.a is used below to access non-exported private symbols used in the test:
|
||||||
|
# libosmo-gprs-rlcmac.a is used below to access non-exported private symbols used in the test:
|
||||||
gmm_prim_test_SOURCES = gmm_prim_test.c
|
gmm_prim_test_SOURCES = gmm_prim_test.c
|
||||||
gmm_prim_test_LDADD = \
|
gmm_prim_test_LDADD = \
|
||||||
$(top_builddir)/src/gmm/libosmo-gprs-gmm.la \
|
$(top_builddir)/src/gmm/libosmo-gprs-gmm.la \
|
||||||
$(top_builddir)/src/llc/.libs/libosmo-gprs-llc.a \
|
$(top_builddir)/src/llc/.libs/libosmo-gprs-llc.a \
|
||||||
|
$(top_builddir)/src/rlcmac/.libs/libosmo-gprs-rlcmac.a \
|
||||||
|
$(top_builddir)/src/csn1/libosmo-csn1.la \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOGSM_LIBS) \
|
$(LIBOSMOGSM_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -28,7 +28,11 @@
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
#include <osmocom/core/fsm.h>
|
#include <osmocom/core/fsm.h>
|
||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/core/timer_compat.h>
|
||||||
|
#include <osmocom/core/select.h>
|
||||||
|
|
||||||
|
#include <osmocom/gprs/rlcmac/rlcmac_private.h>
|
||||||
#include <osmocom/gprs/llc/llc_prim.h>
|
#include <osmocom/gprs/llc/llc_prim.h>
|
||||||
#include <osmocom/gprs/llc/llc_private.h>
|
#include <osmocom/gprs/llc/llc_private.h>
|
||||||
#include <osmocom/gprs/gmm/gmm.h>
|
#include <osmocom/gprs/gmm/gmm.h>
|
||||||
|
@ -133,6 +137,46 @@ static uint8_t pdu_gmm_att_acc[] = {
|
||||||
0xea, 0x71, 0x1b, 0x41
|
0xea, 0x71, 0x1b, 0x41
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
GSM A-I/F DTAP - Routing Area Update Accept
|
||||||
|
Protocol Discriminator: GPRS mobility management messages (8)
|
||||||
|
.... 1000 = Protocol discriminator: GPRS mobility management messages (0x8)
|
||||||
|
0000 .... = Skip Indicator: No indication of selected PLMN (0)
|
||||||
|
DTAP GPRS Mobility Management Message Type: Routing Area Update Accept (0x09)
|
||||||
|
Force to Standby
|
||||||
|
.... 0... = Spare bit(s): 0
|
||||||
|
.... .000 = Force to standby: Force to standby not indicated (0)
|
||||||
|
Update Result
|
||||||
|
.000 .... = Update Result: RA updated (0)
|
||||||
|
GPRS Timer - Periodic RA update timer
|
||||||
|
GPRS Timer: 10 sec
|
||||||
|
000. .... = Unit: value is incremented in multiples of 2 seconds (0)
|
||||||
|
...0 0101 = Timer value: 5
|
||||||
|
Routing Area Identification - RAI: 234-70-5-0
|
||||||
|
Routing area identification: 234-70-5-0
|
||||||
|
Mobile Country Code (MCC): United Kingdom (234)
|
||||||
|
Mobile Network Code (MNC): AMSUK Limited (70)
|
||||||
|
Location Area Code (LAC): 0x0005 (5)
|
||||||
|
Routing Area Code (RAC): 0x00 (0)
|
||||||
|
Mobile Identity - Allocated P-TMSI - TMSI/P-TMSI (0xec999002)
|
||||||
|
Element ID: 0x18
|
||||||
|
Length: 5
|
||||||
|
1111 .... = Unused: 0xf
|
||||||
|
.... 0... = Odd/even indication: Even number of identity digits
|
||||||
|
.... .100 = Mobile Identity Type: TMSI/P-TMSI/M-TMSI (4)
|
||||||
|
TMSI/P-TMSI/M-TMSI/5G-TMSI: 3969486850 (0xec999002)
|
||||||
|
GPRS Timer - Negotiated Ready Timer
|
||||||
|
Element ID: 0x17
|
||||||
|
GPRS Timer: 10 sec
|
||||||
|
000. .... = Unit: value is incremented in multiples of 2 seconds (0)
|
||||||
|
...0 0101 = Timer value: 5
|
||||||
|
*/
|
||||||
|
static uint8_t pdu_gmm_rau_acc[] = {
|
||||||
|
0x08, 0x09, 0x00, 0x05, 0x32, 0xf4, 0x07, 0x00,
|
||||||
|
0x05, 0x00, 0x18, 0x05, 0xf4, 0xec, 0x99, 0x90,
|
||||||
|
0x02, 0x17, 0x05
|
||||||
|
};
|
||||||
|
|
||||||
static uint8_t pdu_gmm_detach_acc[] = {
|
static uint8_t pdu_gmm_detach_acc[] = {
|
||||||
0x08, 0x06, 0x00
|
0x08, 0x06, 0x00
|
||||||
};
|
};
|
||||||
|
@ -145,6 +189,42 @@ int __wrap_osmo_get_rand_id(uint8_t *data, size_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define clock_debug(fmt, args...) \
|
||||||
|
do { \
|
||||||
|
struct timespec ts; \
|
||||||
|
struct timeval tv; \
|
||||||
|
osmo_clock_gettime(CLOCK_MONOTONIC, &ts); \
|
||||||
|
osmo_gettimeofday(&tv, NULL); \
|
||||||
|
fprintf(stdout, "sys={%lu.%06lu}, mono={%lu.%06lu}: " fmt "\n", \
|
||||||
|
tv.tv_sec, tv.tv_usec, ts.tv_sec, ts.tv_nsec/1000, ##args); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void clock_override_enable(bool enable)
|
||||||
|
{
|
||||||
|
osmo_gettimeofday_override = enable;
|
||||||
|
osmo_clock_override_enable(CLOCK_MONOTONIC, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clock_override_set(long sec, long usec)
|
||||||
|
{
|
||||||
|
struct timespec *mono;
|
||||||
|
osmo_gettimeofday_override_time.tv_sec = sec;
|
||||||
|
osmo_gettimeofday_override_time.tv_usec = usec;
|
||||||
|
mono = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
|
||||||
|
mono->tv_sec = sec;
|
||||||
|
mono->tv_nsec = usec*1000;
|
||||||
|
|
||||||
|
clock_debug("clock_override_set");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clock_override_add_debug(long sec, long usec, bool dbg)
|
||||||
|
{
|
||||||
|
osmo_gettimeofday_override_add(sec, usec);
|
||||||
|
osmo_clock_override_add(CLOCK_MONOTONIC, sec, usec*1000);
|
||||||
|
if (dbg)
|
||||||
|
clock_debug("clock_override_add");
|
||||||
|
}
|
||||||
|
#define clock_override_add(sec, usec) clock_override_add_debug(sec, usec, true)
|
||||||
|
|
||||||
int test_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
|
int test_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -252,6 +332,7 @@ int test_gmm_prim_down_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
|
||||||
int test_gmm_prim_llc_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
|
int test_gmm_prim_llc_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
|
||||||
{
|
{
|
||||||
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
|
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
|
||||||
|
struct osmo_gprs_gmm_prim *gmm_prim_tx;
|
||||||
|
|
||||||
switch (llc_prim->oph.sap) {
|
switch (llc_prim->oph.sap) {
|
||||||
case OSMO_GPRS_LLC_SAP_LLGMM:
|
case OSMO_GPRS_LLC_SAP_LLGMM:
|
||||||
|
@ -269,6 +350,15 @@ int test_gmm_prim_llc_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_da
|
||||||
printf("%s(): Rx %s TLLI=0x%08x SAPI=%s l3=[%s]\n", __func__, pdu_name,
|
printf("%s(): Rx %s TLLI=0x%08x SAPI=%s l3=[%s]\n", __func__, pdu_name,
|
||||||
llc_prim->ll.tlli, osmo_gprs_llc_sapi_name(llc_prim->ll.sapi),
|
llc_prim->ll.tlli, osmo_gprs_llc_sapi_name(llc_prim->ll.sapi),
|
||||||
osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len));
|
osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len));
|
||||||
|
switch (OSMO_PRIM_HDR(&llc_prim->oph)) {
|
||||||
|
case OSMO_PRIM(OSMO_GPRS_LLC_LL_UNITDATA, PRIM_OP_REQUEST):
|
||||||
|
/* Immediately notify GMM that it was transmitted over the air: */
|
||||||
|
gmm_prim_tx = (struct osmo_gprs_gmm_prim *)gprs_rlcmac_prim_alloc_gmmrr_llc_transmitted_ind(llc_prim->ll.tlli);
|
||||||
|
gmm_prim_tx->oph.sap = OSMO_GPRS_GMM_SAP_GMMRR;
|
||||||
|
gmm_prim_tx->oph.primitive = OSMO_GPRS_GMM_GMMRR_LLC_TRANSMITTED;
|
||||||
|
osmo_gprs_gmm_prim_lower_up(gmm_prim_tx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("%s(): Unexpected Rx %s\n", __func__, pdu_name);
|
printf("%s(): Unexpected Rx %s\n", __func__, pdu_name);
|
||||||
|
@ -286,12 +376,15 @@ static void test_gmm_prim_ms_gmmreg(void)
|
||||||
uint32_t ptmsi = 0x00001234;
|
uint32_t ptmsi = 0x00001234;
|
||||||
uint32_t ptmsi_sig = 0x556677;
|
uint32_t ptmsi_sig = 0x556677;
|
||||||
uint32_t rand_tlli = 0x80001234;
|
uint32_t rand_tlli = 0x80001234;
|
||||||
|
uint32_t tlli;
|
||||||
char *imsi = "1234567890";
|
char *imsi = "1234567890";
|
||||||
char *imei = "42342342342342";
|
char *imei = "42342342342342";
|
||||||
char *imeisv = "4234234234234275";
|
char *imeisv = "4234234234234275";
|
||||||
|
|
||||||
printf("==== %s() [start] ====\n", __func__);
|
printf("==== %s() [start] ====\n", __func__);
|
||||||
|
|
||||||
|
clock_override_set(0, 0);
|
||||||
|
|
||||||
rc = osmo_gprs_gmm_init(OSMO_GPRS_GMM_LOCATION_MS);
|
rc = osmo_gprs_gmm_init(OSMO_GPRS_GMM_LOCATION_MS);
|
||||||
OSMO_ASSERT(rc == 0);
|
OSMO_ASSERT(rc == 0);
|
||||||
osmo_gprs_gmm_enable_gprs(true);
|
osmo_gprs_gmm_enable_gprs(true);
|
||||||
|
@ -338,9 +431,31 @@ static void test_gmm_prim_ms_gmmreg(void)
|
||||||
OSMO_ASSERT(llc_prim);
|
OSMO_ASSERT(llc_prim);
|
||||||
rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
|
rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
|
||||||
OSMO_ASSERT(rc == 0);
|
OSMO_ASSERT(rc == 0);
|
||||||
|
/* update the used ptmsi to align with what was assigned from the network: */
|
||||||
|
ptmsi = 0xea711b41;
|
||||||
|
tlli = gprs_tmsi2tlli(ptmsi, TLLI_LOCAL);
|
||||||
/* As a result, MS answers GMM Attach Complete */
|
/* As a result, MS answers GMM Attach Complete */
|
||||||
/* As a result, MS submits GMMREG ATTACH.cnf */
|
/* As a result, MS submits GMMREG ATTACH.cnf */
|
||||||
|
|
||||||
|
/* Wait for READY timer to expire: */
|
||||||
|
clock_override_add(44, 0); /* 44: See GMM Attach Accept (pdu_gmm_att_acc) feed above */
|
||||||
|
clock_debug("Expect T3314 (READY) timeout");
|
||||||
|
osmo_select_main(0);
|
||||||
|
|
||||||
|
clock_override_add(10*60, 0); /* 44: See GMM Attach Accept (pdu_gmm_att_acc) feed above */
|
||||||
|
clock_debug("Expect T3312 (periodic RAU) timeout");
|
||||||
|
osmo_select_main(0);
|
||||||
|
|
||||||
|
/* Network sends GMM RAU Accept */
|
||||||
|
llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_rau_acc, sizeof(pdu_gmm_rau_acc));
|
||||||
|
OSMO_ASSERT(llc_prim);
|
||||||
|
rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
|
||||||
|
OSMO_ASSERT(rc == 0);
|
||||||
|
/* update the used ptmsi to align with what was assigned from the network: */
|
||||||
|
ptmsi = 0xea711b41;
|
||||||
|
tlli = gprs_tmsi2tlli(ptmsi, TLLI_LOCAL);
|
||||||
|
/* As a result, MS answers GMM RAU Complete */
|
||||||
|
|
||||||
/* ... */
|
/* ... */
|
||||||
|
|
||||||
/* DETACH */
|
/* DETACH */
|
||||||
|
@ -353,7 +468,7 @@ static void test_gmm_prim_ms_gmmreg(void)
|
||||||
OSMO_ASSERT(rc == 0);
|
OSMO_ASSERT(rc == 0);
|
||||||
|
|
||||||
/* Network sends GMM Detach Accept */
|
/* Network sends GMM Detach Accept */
|
||||||
llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_detach_acc, sizeof(pdu_gmm_detach_acc));
|
llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_detach_acc, sizeof(pdu_gmm_detach_acc));
|
||||||
OSMO_ASSERT(llc_prim);
|
OSMO_ASSERT(llc_prim);
|
||||||
rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
|
rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
|
||||||
OSMO_ASSERT(rc == 0);
|
OSMO_ASSERT(rc == 0);
|
||||||
|
@ -379,6 +494,8 @@ static void test_gmm_prim_ms_gmmsm(void)
|
||||||
|
|
||||||
printf("==== %s() [start] ====\n", __func__);
|
printf("==== %s() [start] ====\n", __func__);
|
||||||
|
|
||||||
|
clock_override_set(0, 0);
|
||||||
|
|
||||||
rc = osmo_gprs_gmm_init(OSMO_GPRS_GMM_LOCATION_MS);
|
rc = osmo_gprs_gmm_init(OSMO_GPRS_GMM_LOCATION_MS);
|
||||||
OSMO_ASSERT(rc == 0);
|
OSMO_ASSERT(rc == 0);
|
||||||
osmo_gprs_gmm_enable_gprs(true);
|
osmo_gprs_gmm_enable_gprs(true);
|
||||||
|
@ -460,6 +577,8 @@ int main(int argc, char *argv[])
|
||||||
log_set_print_level(osmo_stderr_target, 1);
|
log_set_print_level(osmo_stderr_target, 1);
|
||||||
log_set_use_color(osmo_stderr_target, 0);
|
log_set_use_color(osmo_stderr_target, 0);
|
||||||
|
|
||||||
|
clock_override_enable(true);
|
||||||
|
|
||||||
test_gmm_prim_ms_gmmreg();
|
test_gmm_prim_ms_gmmreg();
|
||||||
test_gmm_prim_ms_gmmsm();
|
test_gmm_prim_ms_gmmsm();
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,50 @@ DLGLOBAL INFO GMM_MS{Null}: Received Event ENABLE_GPRS_MODE
|
||||||
DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered
|
DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered
|
||||||
DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED
|
DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234)
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234)
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated
|
DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM IDENTITY REQUEST mi_type=IMEI
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM IDENTITY REQUEST mi_type=IMEI
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM IDENTITY RESPONSE
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM IDENTITY RESPONSE
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST
|
||||||
DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response
|
DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM ATTACH ACCEPT
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM ATTACH ACCEPT
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM ATTACH COMPL
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM ATTACH COMPL
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started (expires in 44 seconds)
|
||||||
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED
|
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED
|
||||||
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered
|
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer expired
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 started (expires in 600 seconds)
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 Periodic RAU timer expired
|
||||||
|
DLGLOBAL INFO GMM_MS{Registered}: Received Event RAU_REQUESTED
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM RAU REQUEST
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started (expires in 44 seconds)
|
||||||
|
DLGLOBAL INFO GMM_MS{Registered}: state_chg to RAUInitidated
|
||||||
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Rx GMM RAU ACCEPT upd_result=0x00
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) Tx GMM RAU COMPL
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) READY timer started (expires in 10 seconds)
|
||||||
|
DLGLOBAL INFO GMM_MS{RAUInitidated}: Received Event RAU_ACCEPTED
|
||||||
|
DLGLOBAL INFO GMM_MS{RAUInitidated}: state_chg to Registered
|
||||||
DLGLOBAL INFO Rx from upper layers: GMMREG-DETACH.request
|
DLGLOBAL INFO Rx from upper layers: GMMREG-DETACH.request
|
||||||
DLGLOBAL INFO GMM_MS{Registered}: Received Event DETACH_REQUESTED
|
DLGLOBAL INFO GMM_MS{Registered}: Received Event DETACH_REQUESTED
|
||||||
DLGLOBAL INFO GMM_MS{Registered}: state_chg to DeregisteredInitiated
|
DLGLOBAL INFO GMM_MS{Registered}: state_chg to DeregisteredInitiated
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM DETACH REQUEST (MO)
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) Tx GMM DETACH REQUEST (MO)
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) READY timer started (expires in 10 seconds)
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Rx GMM DETACH ACCEPT (MO) force_standby_indicated=false
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) Rx GMM DETACH ACCEPT (MO) force_standby_indicated=false
|
||||||
DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: Received Event DETACH_ACCEPTED
|
DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: Received Event DETACH_ACCEPTED
|
||||||
DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: state_chg to Deregistered
|
DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: state_chg to Deregistered
|
||||||
DLGLOBAL DEBUG GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ffffffff) free()
|
DLGLOBAL DEBUG GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ffffffff) free()
|
||||||
DLGLOBAL INFO GMM_MS{Deregistered}: Deallocated
|
DLGLOBAL INFO GMM_MS{Deregistered}: Deallocated
|
||||||
DLGLOBAL INFO Rx from upper layers: GMMSM-ESTABLISH.request
|
DLGLOBAL INFO Rx from upper layers: GMMSM-ESTABLISH.request
|
||||||
DLGLOBAL INFO GMM_MS{Null}: Allocated
|
DLGLOBAL INFO GMM_MS{Null}: Allocated
|
||||||
|
@ -33,18 +55,25 @@ DLGLOBAL INFO GMM_MS{Null}: Received Event ENABLE_GPRS_MODE
|
||||||
DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered
|
DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered
|
||||||
DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED
|
DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234)
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234)
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated
|
DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM IDENTITY REQUEST mi_type=IMEI
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM IDENTITY REQUEST mi_type=IMEI
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM IDENTITY RESPONSE
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM IDENTITY RESPONSE
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST
|
||||||
DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response
|
DLGLOBAL INFO Rx from upper layers: GMMREG-SIM_AUTH.response
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM ATTACH ACCEPT
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-00001234:TLLI-80001234) Rx GMM ATTACH ACCEPT
|
||||||
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM ATTACH COMPL
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM ATTACH COMPL
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started (expires in 44 seconds)
|
||||||
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED
|
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED
|
||||||
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered
|
DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered
|
||||||
DLGLOBAL INFO Rx from upper layers: GMMSM-UNITDATA.request
|
DLGLOBAL INFO Rx from upper layers: GMMSM-UNITDATA.request
|
||||||
|
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
|
||||||
|
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started (expires in 44 seconds)
|
||||||
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
==== test_gmm_prim_ms_gmmreg() [start] ====
|
==== test_gmm_prim_ms_gmmreg() [start] ====
|
||||||
|
sys={0.000000}, mono={0.000000}: clock_override_set
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ]
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ]
|
||||||
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3 f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
|
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3 f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
|
||||||
|
@ -8,11 +9,22 @@ test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0x80001234 new_TLL
|
||||||
test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0x80001234 new_tlli=0xea711b41
|
test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0x80001234 new_tlli=0xea711b41
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 03 ]
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 03 ]
|
||||||
test_gmm_prim_up_cb(): Rx GMMREG-ATTACH.confirm accepted=1 allocated_ptmsi=0xea711b41 allocated_ptmsi_sig=0xffffffff
|
test_gmm_prim_up_cb(): Rx GMMREG-ATTACH.confirm accepted=1 allocated_ptmsi=0xea711b41 allocated_ptmsi_sig=0xffffffff
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 05 20 0a 00 05 f4 ea 71 1b 41 ]
|
sys={44.000000}, mono={44.000000}: clock_override_add
|
||||||
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xea711b41 new_TLLI=0xffffffff
|
sys={44.000000}, mono={44.000000}: Expect T3314 (READY) timeout
|
||||||
|
sys={644.000000}, mono={644.000000}: clock_override_add
|
||||||
|
sys={644.000000}, mono={644.000000}: Expect T3312 (periodic RAU) timeout
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LLGMM-SUSPEND.request TLLI=0xea711b41
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 08 03 32 f4 07 00 05 00 00 17 16 0a 00 e5 02 00 00 e1 ]
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xea711b41 new_TLLI=0xec999002
|
||||||
|
test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0xea711b41 new_tlli=0xec999002
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xec999002 SAPI=GMM l3=[08 0a ]
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LLGMM-RESUME.request TLLI=0xec999002
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xec999002 SAPI=GMM l3=[08 05 20 0a 00 05 f4 ec 99 90 02 ]
|
||||||
|
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xec999002 new_TLLI=0xffffffff
|
||||||
test_gmm_prim_up_cb(): Rx GMMREG-DETACH.confirm detach_type='GPRS detach'
|
test_gmm_prim_up_cb(): Rx GMMREG-DETACH.confirm detach_type='GPRS detach'
|
||||||
==== test_gmm_prim_ms_gmmreg() [end] ====
|
==== test_gmm_prim_ms_gmmreg() [end] ====
|
||||||
==== test_gmm_prim_ms_gmmsm() [start] ====
|
==== test_gmm_prim_ms_gmmsm() [start] ====
|
||||||
|
sys={0.000000}, mono={0.000000}: clock_override_set
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 19 55 66 77 17 16 e1 ]
|
||||||
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ]
|
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ]
|
||||||
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3 f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
|
test_gmm_prim_up_cb(): Rx GMMREG-SIM_AUTH.indication ac_ref_nr=2 key_seq=0 rand=e2 a6 f3 f8 bb 9e a7 01 e0 ce 4f 33 64 a9 91 75
|
||||||
|
|
Loading…
Reference in New Issue