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>
This commit is contained in:
Andreas.Eversberg 2011-11-06 20:45:29 +01:00 committed by Harald Welte
parent cbed327965
commit f1f80de007
2 changed files with 19 additions and 8 deletions

View File

@ -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) */

View File

@ -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);