summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2011-11-06 20:45:29 +0100
committerHarald Welte <laforge@gnumonks.org>2011-11-12 23:23:36 +0100
commitf1f80de007aeefb7757d469dcc3869b6c5a89a9a (patch)
tree0495e0f2d128baa88354cf2b32ce580b48c22d5c
parentcbed32796578db7522c1821bdb06d3c1d596ca40 (diff)
gsm/lapdm: Fix TA and power level handling in the ACCH header
Timing advance and power level indicated by MS (measurement reports) and BTS (SI 5/6) are now stored for use at ACCH data link connection. This is part of a set of commit to fix LAPDm to handle datalink connection on ACCH (SAPI 3) This is required to transfer SMS on SACCH of TCH/f or SDCCH/8 (4). Written-by: Andreas Eversberg <jolly@eversberg.eu> Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--include/osmocom/gsm/lapdm.h7
-rw-r--r--src/gsm/lapdm.c20
2 files changed, 19 insertions, 8 deletions
diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h
index adffbebb..52e8fc52 100644
--- a/include/osmocom/gsm/lapdm.h
+++ b/include/osmocom/gsm/lapdm.h
@@ -72,8 +72,8 @@ struct lapdm_msg_ctx {
int lapdm_fmt;
uint8_t chan_nr;
uint8_t link_id;
- uint8_t ta_ind;
- uint8_t tx_power_ind;
+ uint8_t ta_ind; /* TA indicated by network */
+ uint8_t tx_power_ind; /* MS power indicated by network */
};
/*! \brief LAPDm datalink like TS 04.06 / Section 3.5.2 */
@@ -113,6 +113,9 @@ struct lapdm_entity {
/*! \brief pointer to \ref lapdm_channel of which we're part */
struct lapdm_channel *lapdm_ch;
+
+ uint8_t ta; /* TA used and indicated to network */
+ uint8_t tx_power; /* MS power used and indicated to network */
};
/*! \brief the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c
index 7e4b0380..aac203e2 100644
--- a/src/gsm/lapdm.c
+++ b/src/gsm/lapdm.c
@@ -479,6 +479,15 @@ static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg)
if (lctx->more)
msg->l2h[2] |= LAPDm_MORE;
+ /* add ACCH header with last indicated tx-power and TA */
+ if ((mctx->link_id & 0x40)) {
+ struct lapdm_entity *le = mdl->entity;
+
+ msg->l2h = msgb_push(msg, 2);
+ msg->l2h[0] = le->tx_power;
+ msg->l2h[1] = le->ta;
+ }
+
return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
23);
}
@@ -799,17 +808,16 @@ static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
uint8_t sapi = link_id & 7;
struct tlv_parsed tv;
int length;
- uint8_t ta = 0, tx_power = 0;
/* check if the layer3 message length exceeds N201 */
rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
if (TLVP_PRESENT(&tv, RSL_IE_TIMING_ADVANCE)) {
- ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
+ le->ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
}
if (TLVP_PRESENT(&tv, RSL_IE_MS_POWER)) {
- tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
+ le->tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
}
if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
LOGP(DLLAPD, LOGL_ERROR, "unit data request without message "
@@ -828,7 +836,7 @@ static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
}
LOGP(DLLAPD, LOGL_INFO, "sending unit data (tx_power=%d, ta=%d)\n",
- tx_power, ta);
+ le->tx_power, le->ta);
/* Remove RLL header from msgb and set length to L3-info */
msgb_pull_l2h(msg);
@@ -837,8 +845,8 @@ static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
/* Push L1 + LAPDm header on msgb */
msg->l2h = msgb_push(msg, 2 + 3);
- msg->l2h[0] = tx_power;
- msg->l2h[1] = ta;
+ msg->l2h[0] = le->tx_power;
+ msg->l2h[1] = le->ta;
msg->l2h[2] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, dl->dl.cr.loc2rem.cmd);
msg->l2h[3] = LAPDm_CTRL_U(LAPDm_U_UI, 0);
msg->l2h[4] = LAPDm_LEN(length);