llc: Implement LLGM-TRIGGER.req
Change-Id: Id1af5912f407fe055a59a4bb217936307697975f
This commit is contained in:
parent
409bb636d9
commit
8700df25d7
|
@ -88,6 +88,16 @@ static inline const char *osmo_gprs_llc_bssgp_prim_type_name(enum osmo_gprs_llc_
|
|||
return get_value_string(osmo_gprs_llc_bssgp_prim_type_names, val);
|
||||
}
|
||||
|
||||
/* TS 04.64 Section 7.2.1.3 LLGMM-TRIGGER */
|
||||
/* 3GPP TS 24.008 2.1.2 "Cell Notification" is considered a different trigger
|
||||
* type than Cell Update since lower layers behave different (tx LLC NULL vs UI
|
||||
* frame). Furthermore, the one knowing about requirement to use one or the other
|
||||
* is the upper layer (GMM), as well as the one responsible of READY timer. */
|
||||
enum osmo_gprs_llc_llgmm_trigger_type {
|
||||
OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_UPDATE,
|
||||
OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_NOTIFICATION,
|
||||
OSMO_GPRS_LLC_LLGM_TRIGGER_PAGE_RESP,
|
||||
};
|
||||
|
||||
/* Parameters for OSMO_GPRS_LLC_LLGMM_* prims */
|
||||
struct osmo_gprs_llc_llgmm_prim {
|
||||
|
@ -104,7 +114,7 @@ struct osmo_gprs_llc_llgmm_prim {
|
|||
} assign_req;
|
||||
/* OSMO_GPRS_LLC_LLGMM_TRIGGER | Req */
|
||||
struct {
|
||||
uint8_t cause;
|
||||
uint8_t cause; /* enum osmo_gprs_llc_llgmm_trigger_type */
|
||||
} trigger_req;
|
||||
/* OSMO_GPRS_LLC_LLGMM_SUSPEND | Req */
|
||||
struct {
|
||||
|
|
|
@ -323,6 +323,7 @@ int gprs_llc_lle_tx_xid(const struct gprs_llc_lle *lle, uint8_t *xid_payload, un
|
|||
int gprs_llc_lle_tx_xid_req(struct gprs_llc_lle *lle, uint8_t *l3par, unsigned int l3par_len);
|
||||
int gprs_llc_lle_tx_xid_resp(struct gprs_llc_lle *lle, uint8_t *l3par, unsigned int l3par_len);
|
||||
int gprs_llc_lle_tx_ui(struct gprs_llc_lle *lle, uint8_t *l3_pdu, size_t l3_pdu_len, bool encryptable);
|
||||
int gprs_llc_lle_tx_null(const struct gprs_llc_lle *lle);
|
||||
|
||||
/* llc_prim.c: */
|
||||
struct osmo_gprs_llc_prim *gprs_llc_prim_alloc(enum osmo_gprs_llc_prim_sap sap, unsigned int type,
|
||||
|
|
|
@ -292,6 +292,46 @@ int gprs_llc_lle_tx_xid(const struct gprs_llc_lle *lle, uint8_t *xid_payload, un
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* 6.4.1.7 NULL command */
|
||||
int gprs_llc_lle_tx_null(const struct gprs_llc_lle *lle)
|
||||
{
|
||||
int rc;
|
||||
struct msgb *msg;
|
||||
struct gprs_llc_pdu_decoded pdu_dec = {
|
||||
.sapi = lle->sapi,
|
||||
.fmt = OSMO_GPRS_LLC_FMT_U,
|
||||
.func = OSMO_GPRS_LLC_FUNC_NULL,
|
||||
.flags = 0 /* P=0 */,
|
||||
};
|
||||
struct osmo_gprs_llc_prim *llc_prim;
|
||||
|
||||
/* LLC payload is put directly below: */
|
||||
if (g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_SGSN)
|
||||
llc_prim = gprs_llc_prim_alloc_bssgp_dl_unitdata_req(lle->llme->tlli, NULL, 4096 - sizeof(llc_prim));
|
||||
else
|
||||
llc_prim = gprs_llc_prim_alloc_grr_unitdata_req(lle->llme->tlli, NULL, 4096 - sizeof(llc_prim));
|
||||
msg = llc_prim->oph.msg;
|
||||
msg->l3h = msg->tail;
|
||||
|
||||
rc = gprs_llc_pdu_encode(msg, &pdu_dec);
|
||||
if (rc < 0) {
|
||||
LOGLLC(LOGL_NOTICE, "Failed to encode U DM\n");
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
if (g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_MS) {
|
||||
llc_prim->bssgp.ll_pdu = msgb_l3(msg);
|
||||
llc_prim->bssgp.ll_pdu_len = msgb_l3len(msg);
|
||||
} else {
|
||||
llc_prim->grr.ll_pdu = msgb_l3(msg);
|
||||
llc_prim->grr.ll_pdu_len = msgb_l3len(msg);
|
||||
}
|
||||
|
||||
/* Send BSSGP-DL-UNITDATA.req (SGSN) / GRR-UNITDATA.req (MS) */
|
||||
gprs_llc_prim_call_down_cb(llc_prim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Transmit a UI frame over the given SAPI:
|
||||
'encryptable' indicates whether particular message can be encrypted according
|
||||
to 3GPP TS 24.008 § 4.7.1.2
|
||||
|
|
|
@ -274,6 +274,46 @@ ret_free:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* 7.2.1.3 LLGMM-TRIGGER.req (SGSN):*/
|
||||
static int llc_prim_handle_llgmm_trigger_req(struct osmo_gprs_llc_prim *llc_prim)
|
||||
{
|
||||
struct gprs_llc_lle *lle;
|
||||
int rc;
|
||||
struct gprs_llc_llme *llme = gprs_llc_find_llme_by_tlli(llc_prim->llgmm.tlli);
|
||||
|
||||
if (!llme) {
|
||||
LOGLLC(LOGL_NOTICE, "Rx %s: Unknown TLLI 0x%08x\n",
|
||||
osmo_gprs_llc_prim_name(llc_prim), llc_prim->llgmm.tlli);
|
||||
rc = -ENOKEY;
|
||||
goto ret_free;
|
||||
}
|
||||
LOGLLME(llme, LOGL_INFO, "%s\n", osmo_gprs_llc_prim_name(llc_prim));
|
||||
|
||||
lle = gprs_llc_llme_get_lle(llme, OSMO_GPRS_LLC_SAPI_GMM);
|
||||
|
||||
/* "If there is a frame waiting to be transmitted in the MS, then this
|
||||
* frame shall be transmitted on the corresponding SAPI or optionally a
|
||||
* UI frame with no information field shall be transmitted on any SAPI.
|
||||
* Otherwise if Cause indicates Cell Update and if Cell Notification is
|
||||
* indicated by the SGSN (see 3GPP TS 24.008 [8a]), then a NULL frame
|
||||
* with P=0 shall be transmitted on any SAPI."
|
||||
*/
|
||||
switch (llc_prim->llgmm.trigger_req.cause) {
|
||||
case OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_NOTIFICATION:
|
||||
rc = gprs_llc_lle_tx_null(lle);
|
||||
break;
|
||||
case OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_UPDATE:
|
||||
case OSMO_GPRS_LLC_LLGM_TRIGGER_PAGE_RESP:
|
||||
default:
|
||||
rc = gprs_llc_lle_tx_ui(lle, NULL, 0, false);
|
||||
break;
|
||||
}
|
||||
|
||||
ret_free:
|
||||
msgb_free(llc_prim->oph.msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* 7.2.1.4 LLGMM-SUSPEND.req (MS/SGSN):*/
|
||||
static int llc_prim_handle_llgmm_suspend_req(struct osmo_gprs_llc_prim *llc_prim)
|
||||
{
|
||||
|
@ -332,7 +372,7 @@ int gprs_llc_prim_llgmm_upper_down(struct osmo_gprs_llc_prim *llc_prim)
|
|||
break;
|
||||
case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_TRIGGER, PRIM_OP_REQUEST):
|
||||
OSMO_ASSERT(g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_MS);
|
||||
rc = gprs_llc_prim_handle_unsupported(llc_prim);
|
||||
rc = llc_prim_handle_llgmm_trigger_req(llc_prim);
|
||||
break;
|
||||
case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_SUSPEND, PRIM_OP_REQUEST):
|
||||
OSMO_ASSERT(g_llc_ctx->location == OSMO_GPRS_LLC_LOCATION_MS ||
|
||||
|
|
|
@ -172,13 +172,31 @@ static void test_llc_prim_ms(void)
|
|||
rc = osmo_gprs_llc_prim_upper_down(llc_prim);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
/* Rx LLC-GMM-Attach-Req at MS from SGSN (should be a response message
|
||||
/* Rx LLC-GMM-Attach-Accept at MS from SGSN (should be a response message
|
||||
* but we don't care about upper layers here): */
|
||||
llc_prim = osmo_gprs_llc_prim_alloc_grr_unitdata_ind(tlli, pdu_llc_gmm_att_req, sizeof(pdu_llc_gmm_att_req));
|
||||
OSMO_ASSERT(llc_prim);
|
||||
rc = osmo_gprs_llc_prim_lower_up(llc_prim);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
/* Test GMM asking LLC to transmit a response for a Paging Request: */
|
||||
llc_prim = osmo_gprs_llc_prim_alloc_llgmm_trigger_req(tlli, OSMO_GPRS_LLC_LLGM_TRIGGER_PAGE_RESP);
|
||||
OSMO_ASSERT(llc_prim);
|
||||
rc = osmo_gprs_llc_prim_upper_down(llc_prim);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
/* Test GMM asking LLC to transmit for Cell Update: */
|
||||
llc_prim = osmo_gprs_llc_prim_alloc_llgmm_trigger_req(tlli, OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_UPDATE);
|
||||
OSMO_ASSERT(llc_prim);
|
||||
rc = osmo_gprs_llc_prim_upper_down(llc_prim);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
/* Test GMM asking LLC to transmit for Cell Notification: */
|
||||
llc_prim = osmo_gprs_llc_prim_alloc_llgmm_trigger_req(tlli, OSMO_GPRS_LLC_LLGM_TRIGGER_CELL_NOTIFICATION);
|
||||
OSMO_ASSERT(llc_prim);
|
||||
rc = osmo_gprs_llc_prim_upper_down(llc_prim);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
printf("==== %s() [end] ====\n", __func__);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,12 @@ DLGLOBAL NOTICE Rx LL-UNITDATA.request: unknown TLLI 0xf43cec71, creating LLME o
|
|||
DLGLOBAL INFO Rx from lower layers: GRR-UNITDATA.indication
|
||||
DLGLOBAL DEBUG Rx GRR-UNITDATA.indication: SAPI=1 (GMM), UI func=UI C/R=0 PM=0 E=0 IP=0 N(U)=0 FCS=f218e2
|
||||
DLGLOBAL DEBUG LLE(ffffffff/f43cec71,GMM){UNASSIGNED} Rx SAPI=1 (GMM), UI func=UI C/R=0 PM=0 E=0 IP=0 N(U)=0 FCS=f218e2
|
||||
DLGLOBAL INFO Rx from upper layers: LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO LLME(ffffffff/f43cec71){UNASSIGNED} LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO Rx from upper layers: LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO LLME(ffffffff/f43cec71){UNASSIGNED} LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO Rx from upper layers: LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO LLME(ffffffff/f43cec71){UNASSIGNED} LLGMM-TRIGGER.request
|
||||
DLGLOBAL INFO Rx from lower layers: BSSGP-UL-UNITDATA.indication
|
||||
DLGLOBAL DEBUG Rx BSSGP-UL-UNITDATA.indication: SAPI=1 (GMM), UI func=UI C/R=0 PM=0 E=0 IP=0 N(U)=0 FCS=f218e2
|
||||
DLGLOBAL NOTICE LLME(ffffffff/e1c5d364){UNASSIGNED} LLC RX: unknown TLLI 0xe1c5d364, creating LLME on the fly
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
==== test_llc_prim_ms() [start] ====
|
||||
test_llc_prim_down_cb(): Rx GRR-UNITDATA.request l3=[01 c0 01 08 01 02 e5 e0 01 0a 00 05 f4 f4 3c ec 71 32 f4 07 00 05 00 17 19 33 43 2b 37 15 9e f9 88 79 cb a2 8c 66 21 e7 26 88 b1 98 87 9c 00 17 05 22 96 cc ]
|
||||
test_llc_prim_up_cb(): Rx LL-UNITDATA.indication TLLI=0xf43cec71 SAPI=GMM l3=[08 01 01 d5 71 00 00 08 29 26 24 00 00 00 00 71 62 f2 24 6c 84 44 04 11 e5 10 00 ]
|
||||
test_llc_prim_down_cb(): Rx GRR-UNITDATA.request l3=[01 c0 05 4a 85 74 ]
|
||||
test_llc_prim_down_cb(): Rx GRR-UNITDATA.request l3=[01 c0 09 ce 0d f7 ]
|
||||
test_llc_prim_down_cb(): Rx GRR-UNITDATA.request l3=[01 e0 1c a2 b3 ]
|
||||
==== test_llc_prim_ms() [end] ====
|
||||
==== test_llc_prim_sgsn() [start] ====
|
||||
test_llc_prim_up_cb(): Rx LL-UNITDATA.indication TLLI=0xe1c5d364 SAPI=GMM l3=[08 01 01 d5 71 00 00 08 29 26 24 00 00 00 00 71 62 f2 24 6c 84 44 04 11 e5 10 00 ]
|
||||
|
|
Loading…
Reference in New Issue