aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gprs')
-rw-r--r--openbsc/src/gprs/gprs_llc.c87
-rw-r--r--openbsc/src/gprs/gprs_llc_vty.c22
2 files changed, 99 insertions, 10 deletions
diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c
index cb581f162..54f06f926 100644
--- a/openbsc/src/gprs/gprs_llc.c
+++ b/openbsc/src/gprs/gprs_llc.c
@@ -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);
diff --git a/openbsc/src/gprs/gprs_llc_vty.c b/openbsc/src/gprs/gprs_llc_vty.c
index 6f0de046e..cb91a3a06 100644
--- a/openbsc/src/gprs/gprs_llc_vty.c
+++ b/openbsc/src/gprs/gprs_llc_vty.c
@@ -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);
}
}