aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo/l1_if.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2016-06-13 15:03:18 +0200
committerHarald Welte <laforge@gnumonks.org>2016-06-15 09:30:24 +0000
commit7158c2ed082eaca6063a501e490e8d3c3b181560 (patch)
tree69af1124768459a67afe6cc2a93f8344aa8e6777 /src/osmo-bts-sysmo/l1_if.c
parenta55b166c6c7af79cbefe8e65fe77b2d61c634d2d (diff)
sysmo: add L3 handle to l1prim messages
Place a layer 3 handle into GSM L1 messages to better match up confirmations to respective requests. This handle is a uint32_t transparently returned in the confirmation messages, so a match-up is easy to add. So far, a GSM L1 confirmation message received for a preceding L1 Request was matched only by the prim_id. That meant that only one instance of the same primitive could be waiting for a confirmation at any given time, or the responses would get mixed up: the struct wait_l1_conf instances entered into the fl1h->wlc_list queue would be returned to a possibly mismatching confirmation handler. (Seen during testing of dyn pdch switching.) Send the hLayer3 handle out via prim_init(), using new static functions to produce handles on different scopes: * l1p_handle_for_trx() * l1p_handle_for_ts() * l1p_handle_for_lchan() (These could possibly move to a more general .h/.c file later.) Remember the hLayer3 handle in * struct wait_l1_conf. Match the incoming confirmations' and stored hLayer3 handles up in, and remove a now obsolete comment from: * is_prim_compat() Since the hLayer3 members are at different byte offsets in GsmL1_Prim_t.u.*, use large switch statements to set/get the value: * In prim_init(), extend existing switch statement to set in GsmL1_Prim_t. * Add l1p_get_hLayer3() to retrieve from GsmL1_Prim_t (could possibly move to a more general .h/.c file later). Change-Id: Ie4533c6cbc160318917e7a672ab6f9a848f01d1b
Diffstat (limited to 'src/osmo-bts-sysmo/l1_if.c')
-rw-r--r--src/osmo-bts-sysmo/l1_if.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 84fad994..14de251e 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -67,6 +67,7 @@ struct wait_l1_conf {
struct llist_head list; /* internal linked list */
struct osmo_timer_list timer; /* timer for L1 timeout */
unsigned int conf_prim_id; /* primitive we expect in response */
+ HANDLE conf_hLayer3; /* layer 3 handle we expect in response */
unsigned int is_sys_prim; /* is this a system (1) or L1 (0) primitive */
l1if_compl_cb *cb;
void *cb_data;
@@ -91,6 +92,58 @@ static void l1if_req_timeout(void *data)
exit(23);
}
+static HANDLE l1p_get_hLayer3(GsmL1_Prim_t *prim)
+{
+ switch (prim->id) {
+ case GsmL1_PrimId_MphInitReq:
+ return prim->u.mphInitReq.hLayer3;
+ case GsmL1_PrimId_MphCloseReq:
+ return prim->u.mphCloseReq.hLayer3;
+ case GsmL1_PrimId_MphConnectReq:
+ return prim->u.mphConnectReq.hLayer3;
+ case GsmL1_PrimId_MphDisconnectReq:
+ return prim->u.mphDisconnectReq.hLayer3;
+ case GsmL1_PrimId_MphActivateReq:
+ return prim->u.mphActivateReq.hLayer3;
+ case GsmL1_PrimId_MphDeactivateReq:
+ return prim->u.mphDeactivateReq.hLayer3;
+ case GsmL1_PrimId_MphConfigReq:
+ return prim->u.mphConfigReq.hLayer3;
+ case GsmL1_PrimId_MphMeasureReq:
+ return prim->u.mphMeasureReq.hLayer3;
+ case GsmL1_PrimId_MphInitCnf:
+ return prim->u.mphInitCnf.hLayer3;
+ case GsmL1_PrimId_MphCloseCnf:
+ return prim->u.mphCloseCnf.hLayer3;
+ case GsmL1_PrimId_MphConnectCnf:
+ return prim->u.mphConnectCnf.hLayer3;
+ case GsmL1_PrimId_MphDisconnectCnf:
+ return prim->u.mphDisconnectCnf.hLayer3;
+ case GsmL1_PrimId_MphActivateCnf:
+ return prim->u.mphActivateCnf.hLayer3;
+ case GsmL1_PrimId_MphDeactivateCnf:
+ return prim->u.mphDeactivateCnf.hLayer3;
+ case GsmL1_PrimId_MphConfigCnf:
+ return prim->u.mphConfigCnf.hLayer3;
+ case GsmL1_PrimId_MphMeasureCnf:
+ return prim->u.mphMeasureCnf.hLayer3;
+ case GsmL1_PrimId_MphTimeInd:
+ case GsmL1_PrimId_MphSyncInd:
+ case GsmL1_PrimId_PhEmptyFrameReq:
+ case GsmL1_PrimId_PhDataReq:
+ case GsmL1_PrimId_PhConnectInd:
+ case GsmL1_PrimId_PhReadyToSendInd:
+ case GsmL1_PrimId_PhDataInd:
+ case GsmL1_PrimId_PhRaInd:
+ break;
+ default:
+ LOGP(DL1C, LOGL_ERROR, "unknown L1 primitive %u\n", prim->id);
+ break;
+ }
+ return 0;
+}
+
+
static int _l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg,
int is_system_prim, l1if_compl_cb *cb, void *data)
{
@@ -118,6 +171,7 @@ static int _l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg,
}
wlc->is_sys_prim = 0;
wlc->conf_prim_id = femtobts_l1prim_req2conf[l1p->id];
+ wlc->conf_hLayer3 = l1p_get_hLayer3(l1p);
wqueue = &fl1h->write_q[MQ_L1_WRITE];
timeout_secs = 30;
} else {
@@ -943,12 +997,12 @@ static int l1if_handle_ind(struct femtol1_hdl *fl1, struct msgb *msg)
static inline int is_prim_compat(GsmL1_Prim_t *l1p, struct wait_l1_conf *wlc)
{
- /* the limitation here is that we cannot have multiple callers
- * sending the same primitive */
if (wlc->is_sys_prim != 0)
return 0;
if (l1p->id != wlc->conf_prim_id)
return 0;
+ if (l1p_get_hLayer3(l1p) != wlc->conf_hLayer3)
+ return 0;
return 1;
}