mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	[GPRS] SGSN: Pass BSSGP SUSPEND/RESUME up to GMM and alter MMCTX state
This commit is contained in:
		
				
					committed by
					
						
						Holger Hans Peter Freyther
					
				
			
			
				
	
			
			
			
						parent
						
							f54e7e2102
						
					
				
				
					commit
					5bfe499366
				
			@@ -11,4 +11,8 @@ int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
 | 
					int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
 | 
				
			||||||
 | 
					int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
 | 
				
			||||||
 | 
							       uint8_t suspend_ref);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _GPRS_GMM_H */
 | 
					#endif /* _GPRS_GMM_H */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@
 | 
				
			|||||||
#include <openbsc/gprs_llc.h>
 | 
					#include <openbsc/gprs_llc.h>
 | 
				
			||||||
#include <openbsc/gprs_ns.h>
 | 
					#include <openbsc/gprs_ns.h>
 | 
				
			||||||
#include <openbsc/gprs_sgsn.h>
 | 
					#include <openbsc/gprs_sgsn.h>
 | 
				
			||||||
 | 
					#include <openbsc/gprs_gmm.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *bssgp_tall_ctx = NULL;
 | 
					void *bssgp_tall_ctx = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -363,6 +364,7 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
 | 
				
			|||||||
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
 | 
								(struct bssgp_normal_hdr *) msgb_bssgph(msg);
 | 
				
			||||||
	struct gprs_ra_id raid;
 | 
						struct gprs_ra_id raid;
 | 
				
			||||||
	uint32_t tlli;
 | 
						uint32_t tlli;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
 | 
						if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
 | 
				
			||||||
	    !TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
 | 
						    !TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) {
 | 
				
			||||||
@@ -378,8 +380,11 @@ static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
 | 
						gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FIXME: pass the SUSPEND request to GMM */
 | 
						/* Inform GMM about the SUSPEND request */
 | 
				
			||||||
	/* SEND SUSPEND_ACK or SUSPEND_NACK */
 | 
						rc = gprs_gmm_rx_suspend(&raid, tlli);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							return bssgp_tx_suspend_nack(msgb_nsei(msg), tlli, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bssgp_tx_suspend_ack(msgb_nsei(msg), tlli, &raid, 0);
 | 
						bssgp_tx_suspend_ack(msgb_nsei(msg), tlli, &raid, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@@ -392,6 +397,8 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
 | 
				
			|||||||
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
 | 
								(struct bssgp_normal_hdr *) msgb_bssgph(msg);
 | 
				
			||||||
	struct gprs_ra_id raid;
 | 
						struct gprs_ra_id raid;
 | 
				
			||||||
	uint32_t tlli;
 | 
						uint32_t tlli;
 | 
				
			||||||
 | 
						uint8_t suspend_ref;
 | 
				
			||||||
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
 | 
						if (!TLVP_PRESENT(tp, BSSGP_IE_TLLI) ||
 | 
				
			||||||
	    !TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA) ||
 | 
						    !TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA) ||
 | 
				
			||||||
@@ -402,13 +409,18 @@ static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tlli = ntohl(*(uint32_t *)TLVP_VAL(tp, BSSGP_IE_TLLI));
 | 
						tlli = ntohl(*(uint32_t *)TLVP_VAL(tp, BSSGP_IE_TLLI));
 | 
				
			||||||
 | 
						suspend_ref = *TLVP_VAL(tp, BSSGP_IE_SUSPEND_REF_NR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DEBUGP(DBSSGP, "BSSGP BVCI=%u TLLI=0x%08x RESUME\n", ctx->bvci, tlli);
 | 
						DEBUGP(DBSSGP, "BSSGP BVCI=%u TLLI=0x%08x RESUME\n", ctx->bvci, tlli);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
 | 
						gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FIXME: pass the RESUME request to GMM */
 | 
						/* Inform GMM about the RESUME request */
 | 
				
			||||||
	/* SEND RESUME_ACK or RESUME_NACK */
 | 
						rc = gprs_gmm_rx_resume(&raid, tlli, suspend_ref);
 | 
				
			||||||
 | 
						if (rc < 0)
 | 
				
			||||||
 | 
							return bssgp_tx_resume_nack(msgb_nsei(msg), tlli, &raid,
 | 
				
			||||||
 | 
										    NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bssgp_tx_resume_ack(msgb_nsei(msg), tlli, &raid);
 | 
						bssgp_tx_resume_ack(msgb_nsei(msg), tlli, &raid);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1270,3 +1270,51 @@ int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sgsn_mm_ctx *mmctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
 | 
				
			||||||
 | 
						if (!mmctx) {
 | 
				
			||||||
 | 
							LOGP(DMM, LOGL_NOTICE, "SUSPEND request for unknown "
 | 
				
			||||||
 | 
								"TLLI=%08x\n", tlli);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mmctx->mm_state != GMM_REGISTERED_NORMAL) {
 | 
				
			||||||
 | 
							LOGP(DMM, LOGL_NOTICE, "SUSPEND request while state "
 | 
				
			||||||
 | 
								"!= REGISTERED (TLLI=%08x)\n", tlli);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Transition from REGISTERED_NORMAL to REGISTERED_SUSPENDED */
 | 
				
			||||||
 | 
						mmctx->mm_state = GMM_REGISTERED_SUSPENDED;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
 | 
				
			||||||
 | 
							       uint8_t suspend_ref)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sgsn_mm_ctx *mmctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* FIXME: make use of suspend reference? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mmctx = sgsn_mm_ctx_by_tlli(tlli, raid);
 | 
				
			||||||
 | 
						if (!mmctx) {
 | 
				
			||||||
 | 
							LOGP(DMM, LOGL_NOTICE, "RESUME request for unknown "
 | 
				
			||||||
 | 
								"TLLI=%08x\n", tlli);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mmctx->mm_state != GMM_REGISTERED_SUSPENDED) {
 | 
				
			||||||
 | 
							LOGP(DMM, LOGL_NOTICE, "RESUME request while state "
 | 
				
			||||||
 | 
								"!= SUSPENDED (TLLI=%08x)\n", tlli);
 | 
				
			||||||
 | 
							/* FIXME: should we not simply ignore it? */
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Transition from SUSPENDED to NORMAL */
 | 
				
			||||||
 | 
						mmctx->mm_state = GMM_REGISTERED_NORMAL;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user