aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_llc.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/gprs/gprs_llc.c')
-rw-r--r--openbsc/src/gprs/gprs_llc.c87
1 files changed, 81 insertions, 6 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);