2012-04-16 18:07:56 +00:00
|
|
|
/* OsmoBTS lchan interface */
|
|
|
|
|
|
|
|
/* (C) 2012 by Holger Hans Peter Freyther
|
|
|
|
*
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-06-16 15:20:01 +00:00
|
|
|
#include <osmocom/core/logging.h>
|
|
|
|
#include <osmo-bts/logging.h>
|
2012-04-16 18:07:56 +00:00
|
|
|
#include <osmo-bts/gsm_data.h>
|
2021-08-15 21:16:20 +00:00
|
|
|
#include <osmo-bts/bts.h>
|
|
|
|
#include <osmo-bts/rsl.h>
|
2012-04-16 18:07:56 +00:00
|
|
|
|
2021-10-06 15:44:19 +00:00
|
|
|
void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr)
|
|
|
|
{
|
|
|
|
lchan->ts = ts;
|
|
|
|
lchan->nr = lchan_nr;
|
|
|
|
lchan->type = GSM_LCHAN_NONE;
|
|
|
|
gsm_lchan_name_update(lchan);
|
|
|
|
|
|
|
|
INIT_LLIST_HEAD(&lchan->sapi_cmds);
|
|
|
|
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
|
|
|
|
}
|
|
|
|
|
2021-08-16 17:05:06 +00:00
|
|
|
void early_rr_ia_delay_cb(void *data)
|
|
|
|
{
|
|
|
|
struct gsm_lchan *lchan = data;
|
|
|
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
|
|
|
|
|
|
|
if (!lchan->early_rr_ia) {
|
|
|
|
/* The IA message has disappeared since the timer was started. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
|
|
|
/* Release has happened since the timer was started. */
|
|
|
|
msgb_free(lchan->early_rr_ia);
|
|
|
|
lchan->early_rr_ia = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Activation is done, send the RR IA now. Put RR IA msg into the AGCH queue of the BTS. */
|
|
|
|
if (bts_agch_enqueue(bts, lchan->early_rr_ia) < 0) {
|
|
|
|
/* if there is no space in the queue: send DELETE IND */
|
|
|
|
rsl_tx_delete_ind(bts, lchan->early_rr_ia->data, lchan->early_rr_ia->len);
|
|
|
|
rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_DELETED);
|
|
|
|
msgb_free(lchan->early_rr_ia);
|
|
|
|
}
|
|
|
|
lchan->early_rr_ia = NULL;
|
|
|
|
}
|
|
|
|
|
2012-04-16 18:07:56 +00:00
|
|
|
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
|
|
|
{
|
2016-06-16 15:20:01 +00:00
|
|
|
DEBUGP(DL1C, "%s state %s -> %s\n",
|
|
|
|
gsm_lchan_name(lchan),
|
|
|
|
gsm_lchans_name(lchan->state),
|
|
|
|
gsm_lchans_name(state));
|
2012-04-16 18:07:56 +00:00
|
|
|
lchan->state = state;
|
2021-08-15 21:16:20 +00:00
|
|
|
|
|
|
|
/* Early Immediate Assignment: if we have a cached early IA pending, send it upon becoming active, or discard it
|
|
|
|
* when releasing. */
|
|
|
|
if (lchan->early_rr_ia) {
|
|
|
|
switch (lchan->state) {
|
|
|
|
case LCHAN_S_ACT_REQ:
|
|
|
|
/* Activation is requested, keep the early IA until active. This allows the BSC to send the IA
|
|
|
|
* even before a dynamic timeslot is done switching to a different pchan kind (experimental). */
|
|
|
|
break;
|
|
|
|
case LCHAN_S_ACTIVE:
|
2021-08-16 17:05:06 +00:00
|
|
|
/* Activation is done, send the RR IA now. Delay a bit more to give Um time to let the lchan
|
|
|
|
* light up for the MS */
|
|
|
|
osmo_timer_del(&lchan->early_rr_ia_delay);
|
|
|
|
osmo_timer_setup(&lchan->early_rr_ia_delay, early_rr_ia_delay_cb, lchan);
|
|
|
|
osmo_timer_schedule(&lchan->early_rr_ia_delay, 0,
|
|
|
|
osmo_tdef_get(abis_T_defs, -15, OSMO_TDEF_US, -1));
|
2021-08-15 21:16:20 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Transition to any other state means whatever IA the BSC has sent shall now not be relevant
|
|
|
|
* anymore. */
|
2021-08-16 17:05:06 +00:00
|
|
|
osmo_timer_del(&lchan->early_rr_ia_delay);
|
2021-08-15 21:16:20 +00:00
|
|
|
msgb_free(lchan->early_rr_ia);
|
|
|
|
lchan->early_rr_ia = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-04-16 18:07:56 +00:00
|
|
|
}
|
2016-08-09 18:15:09 +00:00
|
|
|
|
|
|
|
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
|
|
|
|
{
|
|
|
|
switch (ts->pchan) {
|
|
|
|
case GSM_PCHAN_PDCH:
|
|
|
|
return true;
|
|
|
|
case GSM_PCHAN_TCH_F_PDCH:
|
|
|
|
return (ts->flags & TS_F_PDCH_ACTIVE)
|
|
|
|
&& !(ts->flags & TS_F_PDCH_PENDING_MASK);
|
2021-06-29 10:16:32 +00:00
|
|
|
case GSM_PCHAN_OSMO_DYN:
|
2016-08-09 18:15:09 +00:00
|
|
|
return ts->dyn.pchan_is == GSM_PCHAN_PDCH
|
|
|
|
&& ts->dyn.pchan_want == ts->dyn.pchan_is;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|