mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
22 Commits
debian/0.9
...
debian/0.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57ae3aa256 | ||
|
|
6f3c2f1b91 | ||
|
|
b3994d0dd2 | ||
|
|
0fa1677013 | ||
|
|
a101a5f43e | ||
|
|
fd7223f7e6 | ||
|
|
7cfdff76ca | ||
|
|
a5fee1cb8d | ||
|
|
e5b7ad8119 | ||
|
|
5f7d3cd6d2 | ||
|
|
7ad066c5c3 | ||
|
|
a0fb1bb847 | ||
|
|
dec0ea8fd2 | ||
|
|
8f3a5a2f0b | ||
|
|
749a666d84 | ||
|
|
bd92172bf4 | ||
|
|
fe7724f1d4 | ||
|
|
ac9341c9c3 | ||
|
|
eb2730e646 | ||
|
|
dbf8411b2f | ||
|
|
bab770e493 | ||
|
|
87f424d6d4 |
35
debian/changelog
vendored
35
debian/changelog
vendored
@@ -1,3 +1,38 @@
|
||||
opensgsn (0.9.13-0~jrsantos.5) unstable; urgency=low
|
||||
|
||||
* gprs: Change T3302 to 20 seconds
|
||||
* gprs: Also check tlli_new in sgsn_mm_ctx_by_tlli
|
||||
|
||||
-- Jonathan Santos <jrsantos@jonathanrsantos.com> Thu, 11 Aug 2011 02:57:38 -0400
|
||||
|
||||
opensgsn (0.9.13-0~jrsantos.4) unstable; urgency=low
|
||||
|
||||
* Revert "gprs: Fix bug that caused TLLI to change prematurely"
|
||||
* gprs: Fix premature TLLI change
|
||||
* gprs: Fix retry of ATTACH REQUEST from mobile
|
||||
|
||||
-- Jonathan Santos <jrsantos@jonathanrsantos.com> Sun, 31 Jul 2011 12:56:09 -0400
|
||||
|
||||
opensgsn (0.9.13-0~jrsantos.3) unstable; urgency=low
|
||||
|
||||
* Allow all IMSIs
|
||||
* gprs: Fix segfault on attach caused by MS Radio Access Capability
|
||||
larger than 14 octets
|
||||
* gprs: Fix possible segfault on attach caused by MS Network
|
||||
Capability larger than 4 octets
|
||||
* gprs: Fix bug where SGSN was sending all LLC UI frames with N(U)=0
|
||||
* gprs: Fix bugs that reset LLC sequence numbers improperly
|
||||
* gprs: Fix bug that caused TLLI to change prematurely
|
||||
* gprs: Delete GMM and PDP contexts if ATTACH_REQUEST received from
|
||||
already-attached MS
|
||||
* gprs: Set GMM state to GMM_REGISTERED_NORMAL after ATTACH_COMPLETE
|
||||
received
|
||||
* gprs: Suspend user data transmission during Routing Area Updating
|
||||
* gprs: Fix LLC UI window
|
||||
* gprs: Reset LLC state when Timer 3350 expires
|
||||
|
||||
-- Jonathan Santos <jrsantos@jonathanrsantos.com> Fri, 22 Jul 2011 13:07:05 -0400
|
||||
|
||||
opensgsn (0.9.13-0~jrsantos.2) unstable; urgency=low
|
||||
|
||||
* Fix bug that caused dpkg-gencontrol to fail
|
||||
|
||||
@@ -140,6 +140,8 @@ struct gprs_llc_llme {
|
||||
uint16_t bvci;
|
||||
uint16_t nsei;
|
||||
struct gprs_llc_lle lle[NUM_SAPIS];
|
||||
|
||||
int suspended;
|
||||
};
|
||||
|
||||
extern struct llist_head gprs_llc_llmes;
|
||||
@@ -156,6 +158,9 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
uint32_t old_tlli, uint32_t new_tlli,
|
||||
enum gprs_ciph_algo alg, const uint8_t *kc);
|
||||
|
||||
int gprs_llgmm_suspend(struct gprs_llc_llme *llme);
|
||||
int gprs_llgmm_resume(struct gprs_llc_llme *llme);
|
||||
void gprs_llgmm_reset_state(struct gprs_llc_llme *llme);
|
||||
int gprs_llc_init(const char *cipher_plugin_path);
|
||||
int gprs_llc_vty_init(void);
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ enum gprs_t3350_mode {
|
||||
GMM_T3350_MODE_PTMSI_REALL,
|
||||
};
|
||||
|
||||
#define MS_RADIO_ACCESS_CAPA
|
||||
#define MS_RADIO_ACCESS_CAPA_MAX_LENGTH 255
|
||||
#define MS_NETWORK_CAPA_MAX_LENGTH 32
|
||||
|
||||
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
|
||||
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
|
||||
@@ -78,11 +79,11 @@ struct sgsn_mm_ctx {
|
||||
/* CKSN */
|
||||
enum gprs_ciph_algo ciph_algo;
|
||||
struct {
|
||||
uint8_t buf[14]; /* 10.5.5.12a */
|
||||
uint8_t buf[MS_RADIO_ACCESS_CAPA_MAX_LENGTH]; /* 10.5.5.12a */
|
||||
uint8_t len;
|
||||
} ms_radio_access_capa;
|
||||
struct {
|
||||
uint8_t buf[4]; /* 10.5.5.12 */
|
||||
uint8_t buf[MS_NETWORK_CAPA_MAX_LENGTH]; /* 10.5.5.12 */
|
||||
uint8_t len;
|
||||
} ms_network_capa;
|
||||
uint16_t drx_parms;
|
||||
|
||||
@@ -48,7 +48,7 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||
struct sgsn_mm_ctx *mmctx,
|
||||
uint16_t nsapi,
|
||||
struct tlv_parsed *tp);
|
||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx);
|
||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx, int implicit);
|
||||
|
||||
/* gprs_sndcp.c */
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
|
||||
#define PTMSI_ALLOC
|
||||
|
||||
#define GSM0408_T3302 (10 | GPRS_TMR_2SECONDS)
|
||||
|
||||
/* Section 11.2.2 / Table 11.4 MM timers netowkr side */
|
||||
#define GSM0408_T3322_SECS 6 /* DETACH_REQ -> DETACH_ACC */
|
||||
#define GSM0408_T3350_SECS 6 /* waiting for ATT/RAU/TMSI COMPL */
|
||||
@@ -359,7 +361,7 @@ static int gsm48_tx_gmm_att_ack(struct sgsn_mm_ctx *mm)
|
||||
aa = (struct gsm48_attach_ack *) msgb_put(msg, sizeof(*aa));
|
||||
aa->force_stby = 0; /* not indicated */
|
||||
aa->att_result = 1; /* GPRS only */
|
||||
aa->ra_upd_timer = GPRS_TMR_MINUTE | 10;
|
||||
aa->ra_upd_timer = GSM0408_T3302;
|
||||
aa->radio_prio = 4; /* lowest */
|
||||
gsm48_construct_ra(aa->ra_id.digits, &mm->ra);
|
||||
|
||||
@@ -549,7 +551,6 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx,
|
||||
ctx->t3350_mode = t3350_mode;
|
||||
mmctx_timer_start(ctx, 3350, GSM0408_T3350_SECS);
|
||||
#endif
|
||||
ctx->mm_state = GMM_REGISTERED_NORMAL;
|
||||
return gsm48_tx_gmm_att_ack(ctx);
|
||||
}
|
||||
if (!strlen(ctx->imei)) {
|
||||
@@ -635,6 +636,21 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
|
||||
DEBUGP(DMM, "-> GMM ATTACH REQUEST ");
|
||||
|
||||
if (ctx && ((ctx->mm_state == GMM_REGISTERED_NORMAL) ||
|
||||
(ctx->mm_state == GMM_REGISTERED_SUSPENDED))) {
|
||||
struct sgsn_pdp_ctx *pdp, *pdp2;
|
||||
|
||||
LOGP(DMM, LOGL_NOTICE, "Attach requested by already-attached "
|
||||
"mobile. Deleting existing contexts\n");
|
||||
|
||||
llist_for_each_entry_safe(pdp, pdp2, &ctx->pdp_list, list) {
|
||||
sgsn_delete_pdp_ctx(pdp, 1);
|
||||
}
|
||||
|
||||
sgsn_mm_ctx_free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
/* As per TS 04.08 Chapter 4.7.1.4, the attach request arrives either
|
||||
* with a foreign TLLI (P-TMSI that was allocated to the MS before),
|
||||
* or with random TLLI. */
|
||||
@@ -644,7 +660,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
/* MS network capability 10.5.5.12 */
|
||||
msnc_len = *cur++;
|
||||
msnc = cur;
|
||||
if (msnc_len > 8)
|
||||
if (msnc_len > MS_NETWORK_CAPA_MAX_LENGTH)
|
||||
goto err_inval;
|
||||
cur += msnc_len;
|
||||
|
||||
@@ -675,7 +691,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
/* MS Radio Access Capability 10.5.5.12a */
|
||||
ms_ra_acc_cap_len = *cur++;
|
||||
ms_ra_acc_cap = cur;
|
||||
if (ms_ra_acc_cap_len > 51)
|
||||
if (ms_ra_acc_cap_len > MS_RADIO_ACCESS_CAPA_MAX_LENGTH)
|
||||
goto err_inval;
|
||||
|
||||
/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
|
||||
@@ -689,16 +705,7 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
|
||||
#if 0
|
||||
return gsm48_tx_gmm_att_rej(msg, GMM_CAUSE_IMSI_UNKNOWN);
|
||||
#else
|
||||
/* As a temorary hack, we simply assume that the IMSI exists,
|
||||
* as long as it is part of 'our' network */
|
||||
char mccmnc[16];
|
||||
snprintf(mccmnc, sizeof(mccmnc), "%03d%02d", ra_id.mcc, ra_id.mnc);
|
||||
if (strncmp(mccmnc, mi_string, 5)) {
|
||||
LOGP(DMM, LOGL_INFO, "Rejecting ATTACH REQUESET IMSI=%s\n",
|
||||
mi_string);
|
||||
return gsm48_tx_gmm_att_rej_oldmsg(msg,
|
||||
GMM_CAUSE_GPRS_NOTALLOWED);
|
||||
}
|
||||
/* As a temorary hack, we simply assume that the IMSI exists */
|
||||
ctx = sgsn_mm_ctx_alloc(0, &ra_id);
|
||||
if (!ctx)
|
||||
return gsm48_tx_gmm_att_rej_oldmsg(msg, GMM_CAUSE_NET_FAIL);
|
||||
@@ -785,7 +792,7 @@ static int gsm48_rx_gmm_det_req(struct sgsn_mm_ctx *ctx, struct msgb *msg)
|
||||
llist_for_each_entry_safe(pdp, pdp2, &ctx->pdp_list, list) {
|
||||
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
|
||||
"due to GPRS DETACH REQUEST\n", pdp->nsapi);
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
sgsn_delete_pdp_ctx(pdp, 0);
|
||||
/* FIXME: the callback wants to transmit a DEACT PDP CTX ACK,
|
||||
* which is quite stupid for a MS that has just detached.. */
|
||||
}
|
||||
@@ -819,7 +826,7 @@ static int gsm48_tx_gmm_ra_upd_ack(struct sgsn_mm_ctx *mm)
|
||||
rua = (struct gsm48_ra_upd_ack *) msgb_put(msg, sizeof(*rua));
|
||||
rua->force_stby = 0; /* not indicated */
|
||||
rua->upd_result = 0; /* RA updated */
|
||||
rua->ra_upd_timer = GPRS_TMR_MINUTE | 10;
|
||||
rua->ra_upd_timer = GSM0408_T3302;
|
||||
|
||||
gsm48_construct_ra(rua->ra_id.digits, &mm->ra);
|
||||
|
||||
@@ -879,7 +886,7 @@ static void process_ms_ctx_status(struct sgsn_mm_ctx *mmctx,
|
||||
LOGP(DMM, LOGL_NOTICE, "Dropping PDP context for NSAPI=%u "
|
||||
"due to PDP CTX STATUS IE= 0x%04x\n",
|
||||
pdp->nsapi, pdp_status);
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
sgsn_delete_pdp_ctx(pdp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -936,6 +943,8 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||
return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_MS_ID_NOT_DERIVED);
|
||||
}
|
||||
|
||||
gprs_llgmm_suspend(mmctx->llme);
|
||||
|
||||
/* Store new BVCI/NSEI in MM context (FIXME: delay until we ack?) */
|
||||
msgid2mmctx(mmctx, msg);
|
||||
/* Bump the statistics of received signalling msgs for this MM context */
|
||||
@@ -1023,30 +1032,25 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
|
||||
case GSM48_MT_GMM_ATTACH_COMPL:
|
||||
/* only in case SGSN offered new P-TMSI */
|
||||
DEBUGP(DMM, "-> ATTACH COMPLETE\n");
|
||||
mmctx->mm_state = GMM_REGISTERED_NORMAL;
|
||||
mmctx_timer_stop(mmctx, 3350);
|
||||
mmctx->p_tmsi_old = 0;
|
||||
/* Unassign the old TLLI */
|
||||
mmctx->tlli = mmctx->tlli_new;
|
||||
gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new,
|
||||
GPRS_ALGO_GEA0, NULL);
|
||||
gprs_llgmm_resume(mmctx->llme);
|
||||
break;
|
||||
case GSM48_MT_GMM_RA_UPD_COMPL:
|
||||
/* only in case SGSN offered new P-TMSI */
|
||||
DEBUGP(DMM, "-> ROUTEING AREA UPDATE COMPLETE\n");
|
||||
mmctx_timer_stop(mmctx, 3350);
|
||||
mmctx->p_tmsi_old = 0;
|
||||
/* Unassign the old TLLI */
|
||||
mmctx->tlli = mmctx->tlli_new;
|
||||
gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new,
|
||||
GPRS_ALGO_GEA0, NULL);
|
||||
gprs_llgmm_resume(mmctx->llme);
|
||||
break;
|
||||
case GSM48_MT_GMM_PTMSI_REALL_COMPL:
|
||||
DEBUGP(DMM, "-> PTMSI REALLLICATION COMPLETE\n");
|
||||
mmctx_timer_stop(mmctx, 3350);
|
||||
mmctx->p_tmsi_old = 0;
|
||||
/* Unassign the old TLLI */
|
||||
mmctx->tlli = mmctx->tlli_new;
|
||||
//gprs_llgmm_assign(mmctx->llme, 0xffffffff, mmctx->tlli_new, GPRS_ALGO_GEA0, NULL);
|
||||
break;
|
||||
case GSM48_MT_GMM_AUTH_CIPH_RESP:
|
||||
rc = gsm48_rx_gmm_auth_ciph_resp(mmctx, msg);
|
||||
@@ -1071,8 +1075,8 @@ static void mmctx_timer_cb(void *_mm)
|
||||
case 3350: /* waiting for ATTACH COMPLETE */
|
||||
if (mm->num_T_exp >= 5) {
|
||||
LOGP(DMM, LOGL_NOTICE, "T3350 expired >= 5 times\n");
|
||||
mm->mm_state = GMM_DEREGISTERED;
|
||||
/* FIXME: should we return some error? */
|
||||
gprs_llgmm_resume(mm->llme);
|
||||
gprs_llgmm_reset_state(mm->llme);
|
||||
break;
|
||||
}
|
||||
/* re-transmit the respective msg and re-start timer */
|
||||
@@ -1409,7 +1413,7 @@ static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg)
|
||||
return _gsm48_tx_gsm_deact_pdp_acc(mm, transaction_id);
|
||||
}
|
||||
|
||||
return sgsn_delete_pdp_ctx(pdp);
|
||||
return sgsn_delete_pdp_ctx(pdp, 0);
|
||||
}
|
||||
|
||||
/* Section 9.5.9: Deactivate PDP Context Accept */
|
||||
@@ -1429,7 +1433,7 @@ static int gsm48_rx_gsm_deact_pdp_ack(struct sgsn_mm_ctx *mm, struct msgb *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sgsn_delete_pdp_ctx(pdp);
|
||||
return sgsn_delete_pdp_ctx(pdp, 0);
|
||||
}
|
||||
|
||||
static int gsm48_rx_gsm_status(struct sgsn_mm_ctx *ctx, struct msgb *msg)
|
||||
@@ -1453,7 +1457,7 @@ static void pdpctx_timer_cb(void *_pdp)
|
||||
if (pdp->num_T_exp >= 4) {
|
||||
LOGP(DMM, LOGL_NOTICE, "T3395 expired >= 5 times\n");
|
||||
pdp->state = PDP_STATE_INACTIVE;
|
||||
sgsn_delete_pdp_ctx(pdp);
|
||||
sgsn_delete_pdp_ctx(pdp, 0);
|
||||
break;
|
||||
}
|
||||
gsm48_tx_gsm_deact_pdp_req(pdp, GSM_CAUSE_NET_FAIL);
|
||||
@@ -1522,7 +1526,12 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme)
|
||||
int rc = -EINVAL;
|
||||
|
||||
bssgp_parse_cell_id(&ra_id, msgb_bcid(msg));
|
||||
mmctx = sgsn_mm_ctx_by_tlli(msgb_tlli(msg), &ra_id);
|
||||
mmctx = sgsn_mm_ctx_by_tlli(llme->tlli, &ra_id);
|
||||
|
||||
if (!mmctx && (llme->old_tlli != 0xffffffff)) {
|
||||
mmctx = sgsn_mm_ctx_by_tlli(llme->old_tlli, &ra_id);
|
||||
}
|
||||
|
||||
if (mmctx) {
|
||||
msgid2mmctx(mmctx, msg);
|
||||
rate_ctr_inc(&mmctx->ctrg->ctr[GMM_CTR_PKTS_SIG_IN]);
|
||||
|
||||
@@ -340,7 +340,7 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
|
||||
struct gprs_llc_llme *llme;
|
||||
LOGP(DLLC, LOGL_ERROR, "LLC TX: unknown TLLI 0x%08x, "
|
||||
"creating LLME on the fly\n", msgb_tlli(msg));
|
||||
llme = llme_alloc(msgb_tlli(msg));
|
||||
llme = llme_alloc(tlli_foreign2local(msgb_tlli(msg)));
|
||||
lle = &llme->lle[sapi];
|
||||
}
|
||||
|
||||
@@ -350,6 +350,12 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
if ((sapi != GPRS_SAPI_GMM) && lle->llme->suspended) {
|
||||
LOGP(DLLC, LOGL_DEBUG, "LLC TX: suspended TLLI 0x08x, "
|
||||
"dropping UI frame\n", msgb_tlli(msg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update LLE's (BVCI, NSEI) tuple */
|
||||
lle->llme->bvci = msgb_bvci(msg);
|
||||
lle->llme->nsei = msgb_nsei(msg);
|
||||
@@ -476,17 +482,21 @@ static int gprs_llc_hdr_rx(struct gprs_llc_hdr_parsed *gph,
|
||||
}
|
||||
break;
|
||||
case GPRS_LLC_UI:
|
||||
if (gph->seq_tx < lle->vu_recv) {
|
||||
LOGP(DLLC, LOGL_NOTICE, "TLLI=%08x dropping UI, vurecv %u <= %u\n",
|
||||
lle->llme ? lle->llme->tlli : -1,
|
||||
gph->seq_tx, lle->vu_recv);
|
||||
return -EIO;
|
||||
}
|
||||
/* Increment the sequence number that we expect in the next frame */
|
||||
lle->vu_recv = (gph->seq_tx + 1) % 512;
|
||||
/* Increment Overflow Counter */
|
||||
if ((gph->seq_tx + 1) / 512)
|
||||
lle->oc_ui_recv += 512;
|
||||
{
|
||||
int delta = (lle->vu_recv - gph->seq_tx) & 0x1ff;
|
||||
if (0 < delta && delta < 32) {
|
||||
LOGP(DLLC, LOGL_NOTICE, "TLLI=%08x dropping UI, vurecv %u <= %u\n",
|
||||
lle->llme ? lle->llme->tlli : -1,
|
||||
gph->seq_tx, lle->vu_recv);
|
||||
return -EIO;
|
||||
}
|
||||
/* Increment the sequence number that we expect in the next frame */
|
||||
lle->vu_recv = (gph->seq_tx + 1) & 0x1ff;
|
||||
/* Increment Overflow Counter */
|
||||
if (lle->vu_recv == 0) {
|
||||
lle->oc_ui_recv += 512;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -808,12 +818,12 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
* received from peer. */
|
||||
if (llme->old_tlli != 0xffffffff) {
|
||||
llme->old_tlli = 0xffffffff;
|
||||
llme->tlli = new_tlli;
|
||||
llme->tlli = tlli_foreign2local(new_tlli);
|
||||
} else {
|
||||
/* If TLLI old == 0xffffffff was assigned to LLME, then this is
|
||||
* TLLI assignmemt according to 8.3.1 */
|
||||
llme->old_tlli = 0xffffffff;
|
||||
llme->tlli = new_tlli;
|
||||
llme->tlli = tlli_foreign2local(new_tlli);
|
||||
llme->state = GPRS_LLMS_ASSIGNED;
|
||||
/* 8.5.3.1 For all LLE's */
|
||||
for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
|
||||
@@ -828,8 +838,8 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
/* TLLI Change 8.3.2 */
|
||||
/* Both TLLI Old and TLLI New are assigned; use New when
|
||||
* (re)transmitting. Accept toth Old and New on Rx */
|
||||
llme->old_tlli = llme->tlli;
|
||||
llme->tlli = new_tlli;
|
||||
llme->old_tlli = tlli_foreign2local(old_tlli);
|
||||
llme->tlli = tlli_foreign2local(new_tlli);
|
||||
llme->state = GPRS_LLMS_ASSIGNED;
|
||||
} else if (old_tlli != 0xffffffff && new_tlli == 0xffffffff) {
|
||||
/* TLLI Unassignment 8.3.3) */
|
||||
@@ -846,6 +856,42 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gprs_llgmm_suspend(struct gprs_llc_llme* llme)
|
||||
{
|
||||
llme->suspended = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gprs_llgmm_resume(struct gprs_llc_llme* llme)
|
||||
{
|
||||
llme->suspended = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gprs_llgmm_reset_state(struct gprs_llc_llme *llme)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (llme == 0)
|
||||
{
|
||||
LOGP(DLLC, LOGL_ERROR, "LLC TX: trying to reset LLC states "
|
||||
"but passed null llme by gmm\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGP(DLLC, LOGL_NOTICE, "LLC RX: reset state variable for TLLI 0x%08x",
|
||||
llme->tlli);
|
||||
/* 8.5.3.1 For all LLE's */
|
||||
for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
|
||||
struct gprs_llc_lle *l = &llme->lle[i];
|
||||
l->vu_recv = 0; /* lets not mess with send state variable now */
|
||||
/* l->vu_send = l->vu_recv = 0; */
|
||||
l->retrans_ctr = 0;
|
||||
l->state = GPRS_LLES_ASSIGNED_ADM;
|
||||
/* FIXME Set parameters according to table 9 */
|
||||
}
|
||||
}
|
||||
|
||||
int gprs_llc_init(const char *cipher_plugin_path)
|
||||
{
|
||||
return gprs_cipher_load(cipher_plugin_path);
|
||||
|
||||
@@ -97,7 +97,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||
int tlli_type;
|
||||
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if (tlli == ctx->tlli &&
|
||||
if ((tlli == ctx->tlli || tlli == ctx->tlli_new) &&
|
||||
ra_id_equals(raid, &ctx->ra))
|
||||
return ctx;
|
||||
}
|
||||
@@ -108,14 +108,14 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if ((ctx->p_tmsi | 0xC0000000) == tlli ||
|
||||
(ctx->p_tmsi_old && (ctx->p_tmsi_old | 0xC0000000) == tlli)) {
|
||||
ctx->tlli = tlli;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TLLI_FOREIGN:
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if (tlli == tlli_foreign(ctx->tlli) &&
|
||||
if ((tlli == tlli_foreign(ctx->tlli) ||
|
||||
tlli == tlli_foreign(ctx->tlli_new)) &&
|
||||
ra_id_equals(raid, &ctx->ra))
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -208,12 +208,20 @@ struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||
}
|
||||
|
||||
/* SGSN wants to delete a PDP context */
|
||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx)
|
||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx, int implicit)
|
||||
{
|
||||
LOGP(DGPRS, LOGL_ERROR, "Delete PDP Context\n");
|
||||
|
||||
if (implicit != 0) {
|
||||
/* Deactivate the SNDCP layer */
|
||||
sndcp_sm_deactivate_ind(&pctx->mm->llme->lle[pctx->sapi], pctx->nsapi);
|
||||
}
|
||||
|
||||
/* FIXME: decide if we need teardown or not ! */
|
||||
return gtp_delete_context_req(pctx->ggsn->gsn, pctx->lib, pctx, 1);
|
||||
return gtp_delete_context_req(pctx->ggsn->gsn,
|
||||
pctx->lib,
|
||||
implicit == 0 ? pctx : NULL,
|
||||
1);
|
||||
}
|
||||
|
||||
struct cause_map {
|
||||
@@ -312,6 +320,10 @@ static int delete_pdp_conf(struct pdp_t *pdp, void *cbp, int cause)
|
||||
DEBUGP(DGPRS, "Received DELETE PDP CTX CONF, cause=%d(%s)\n",
|
||||
cause, get_value_string(gtp_cause_strs, cause));
|
||||
|
||||
if (!pctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Deactivate the SNDCP layer */
|
||||
sndcp_sm_deactivate_ind(&pctx->mm->llme->lle[pctx->sapi], pctx->nsapi);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user