[GPRS] LLC: Implement per-SAPI default values for LLC parameters

This commit is contained in:
Harald Welte 2010-06-03 07:11:04 +02:00
parent ef1bef751d
commit df270ada68
3 changed files with 114 additions and 11 deletions

View File

@ -76,6 +76,19 @@ enum gprs_llc_llme_state {
GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */
};
/* Section 8.9.9 LLC layer parameter default values */
struct gprs_llc_params {
uint16_t iov_i_exp;
uint16_t t200_201;
uint16_t n200;
uint16_t n201_u;
uint16_t n201_i;
uint16_t mD;
uint16_t mU;
uint16_t kD;
uint16_t kU;
};
/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
struct gprs_llc_lle {
struct llist_head list;
@ -96,8 +109,9 @@ struct gprs_llc_lle {
uint16_t vu_send;
uint16_t vu_recv;
unsigned int n200;
unsigned int retrans_ctr;
struct gprs_llc_params params;
};
#define NUM_SAPIS 16

View File

@ -36,11 +36,79 @@
#include <openbsc/gprs_llc.h>
#include <openbsc/crc24.h>
/* Section 8.9.9 LLC layer parameter default values */
static const struct gprs_llc_params llc_default_params[] = {
[1] = {
.t200_201 = 5,
.n200 = 3,
.n201_u = 400,
},
[2] = {
.t200_201 = 5,
.n200 = 3,
.n201_u = 270,
},
[3] = {
.iov_i_exp = 27,
.t200_201 = 5,
.n200 = 3,
.n201_u = 500,
.n201_i = 1503,
.mD = 1520,
.mU = 1520,
.kD = 16,
.kU = 16,
},
[5] = {
.iov_i_exp = 27,
.t200_201 = 10,
.n200 = 3,
.n201_u = 500,
.n201_i = 1503,
.mD = 760,
.mU = 760,
.kD = 8,
.kU = 8,
},
[7] = {
.t200_201 = 20,
.n200 = 3,
.n201_u = 270,
},
[8] = {
.t200_201 = 20,
.n200 = 3,
.n201_u = 270,
},
[9] = {
.iov_i_exp = 27,
.t200_201 = 20,
.n200 = 3,
.n201_u = 500,
.n201_i = 1503,
.mD = 380,
.mU = 380,
.kD = 4,
.kU = 4,
},
[11] = {
.iov_i_exp = 27,
.t200_201 = 40,
.n200 = 3,
.n201_u = 500,
.n201_i = 1503,
.mD = 190,
.mU = 190,
.kD = 2,
.kU = 2,
},
};
LLIST_HEAD(gprs_llc_llmes);
void *llc_tall_ctx;
/* lookup LLC Entity based on DLCI (TLLI+SAPI tuple) */
static struct gprs_llc_lle *lle_by_tlli_sapi(uint32_t tlli, uint32_t sapi)
static struct gprs_llc_lle *lle_by_tlli_sapi(uint32_t tlli, uint8_t sapi)
{
struct gprs_llc_llme *llme;
@ -51,7 +119,7 @@ static struct gprs_llc_lle *lle_by_tlli_sapi(uint32_t tlli, uint32_t sapi)
return NULL;
}
static void lle_init(struct gprs_llc_llme *llme, uint32_t sapi)
static void lle_init(struct gprs_llc_llme *llme, uint8_t sapi)
{
struct gprs_llc_lle *lle = &llme->lle[sapi];
@ -59,8 +127,8 @@ static void lle_init(struct gprs_llc_llme *llme, uint32_t sapi)
lle->sapi = sapi;
lle->state = GPRS_LLES_UNASSIGNED;
/* FIXME: Initialize according to parameters from SAPI9 */
/* Initialize according to parameters */
memcpy(&lle->params, &llc_default_params[sapi], sizeof(lle->params));
}
static struct gprs_llc_llme *llme_alloc(uint32_t tlli)
@ -150,7 +218,7 @@ static void t200_expired(void *data)
/* 8.5.1.3: Expiry of T200 */
if (lle->retrans_ctr >= lle->n200) {
if (lle->retrans_ctr >= lle->params.n200) {
/* FIXME: LLGM-STATUS-IND, LL-RELEASE-IND/CNF */
lle->state = GPRS_LLES_ASSIGNED_ADM;
}
@ -174,7 +242,7 @@ static void t201_expired(void *data)
{
struct gprs_llc_lle *lle = data;
if (lle->retrans_ctr < lle->n200) {
if (lle->retrans_ctr < lle->params.n200) {
/* FIXME: transmit apropriate supervisory frame (8.6.4.1) */
/* FIXME: set timer T201 */
lle->retrans_ctr++;
@ -248,6 +316,13 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
llme = llme_alloc(msgb_tlli(msg));
lle = &llme->lle[sapi];
}
if (msg->len > lle->params.n201_u) {
LOGP(DLLC, LOGL_ERROR, "Cannot Tx %u bytes (N201-U=%u)\n",
msg->len, lle->params.n201_u);
return -EFBIG;
}
/* Update LLE's (BVCI, NSEI) tuple */
lle->llme->bvci = msgb_bvci(msg);
lle->llme->nsei = msgb_nsei(msg);

View File

@ -52,14 +52,21 @@ struct value_string gprs_llc_state_strs[] = {
static void vty_dump_lle(struct vty *vty, struct gprs_llc_lle *lle)
{
struct gprs_llc_params *par = &lle->params;
vty_out(vty, " SAPI %2u State %s VUsend=%u, VUrecv=%u", lle->sapi,
get_value_string(gprs_llc_state_strs, lle->state),
lle->vu_send, lle->vu_recv);
vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, N200=%u, RetransCtr=%u%s",
lle->v_sent, lle->v_ack, lle->v_recv, lle->n200,
vty_out(vty, " Vsent=%u Vack=%u Vrecv=%u, RetransCtr=%u%s",
lle->v_sent, lle->v_ack, lle->v_recv,
lle->retrans_ctr, VTY_NEWLINE);
vty_out(vty, " T200=%u, N200=%u, N201-U=%u, N201-I=%u, mD=%u, "
"mU=%u, kD=%u, kU=%u%s", par->t200_201, par->n200,
par->n201_u, par->n201_i, par->mD, par->mU, par->kD,
par->kU, VTY_NEWLINE);
}
static uint8_t valid_sapis[] = { 1, 2, 3, 5, 7, 8, 9, 11 };
static void vty_dump_llme(struct vty *vty, struct gprs_llc_llme *llme)
{
unsigned int i;
@ -67,8 +74,15 @@ static void vty_dump_llme(struct vty *vty, struct gprs_llc_llme *llme)
vty_out(vty, "TLLI %08x (Old TLLI %08x) BVCI=%u NSEI=%u: State %s%s",
llme->tlli, llme->old_tlli, llme->bvci, llme->nsei,
get_value_string(gprs_llc_state_strs, llme->state), VTY_NEWLINE);
for (i = 0; i < ARRAY_SIZE(llme->lle); i++) {
struct gprs_llc_lle *lle = &llme->lle[i];
for (i = 0; i < ARRAY_SIZE(valid_sapis); i++) {
struct gprs_llc_lle *lle;
uint8_t sapi = valid_sapis[i];
if (sapi >= ARRAY_SIZE(llme->lle))
continue;
lle = &llme->lle[sapi];
vty_dump_lle(vty, lle);
}
}