aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/pcu/pcuif_proto.h15
-rw-r--r--src/bts.cpp6
-rw-r--r--src/gprs_pcu.h2
-rw-r--r--src/pcu_l1_if.cpp34
-rw-r--r--src/pcu_l1_if.h1
5 files changed, 51 insertions, 7 deletions
diff --git a/include/osmocom/pcu/pcuif_proto.h b/include/osmocom/pcu/pcuif_proto.h
index 693a1d53..1dda160d 100644
--- a/include/osmocom/pcu/pcuif_proto.h
+++ b/include/osmocom/pcu/pcuif_proto.h
@@ -3,10 +3,12 @@
#include <osmocom/gsm/l1sap.h>
#include <arpa/inet.h>
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
-#define PCU_IF_VERSION 0x0a
+#define PCU_IF_VERSION 0x0b
#define TXT_MAX_LEN 128
/* msg_type */
@@ -269,6 +271,17 @@ struct gsm_pcu_if_neigh_addr_cnf {
} cgi_ps;
} __attribute__ ((packed));
+/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request
+ * (data_req) under SAPI PCU_IF_SAPI_PCH_DT. */
+struct gsm_pcu_if_pch_dt {
+ /* TLLI as reference for confirmation */
+ uint32_t tlli;
+ /* IMSI (to derive paging group) */
+ char imsi[OSMO_IMSI_BUF_SIZE];
+ /* GSM mac-block (with immediate assignment message) */
+ uint8_t data[GSM_MACBLOCK_LEN];
+} __attribute__((packed));
+
struct gsm_pcu_if {
/* context based information */
uint8_t msg_type; /* message type */
diff --git a/src/bts.cpp b/src/bts.cpp
index 33ad4a6e..504ba27d 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -1103,7 +1103,6 @@ int bts_rcv_ptcch_rach(struct gprs_rlcmac_bts *bts, const struct rach_ind_params
void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, const struct gprs_rlcmac_dl_tbf *tbf)
{
- uint16_t pgroup = ms_paging_group(tbf_ms(tbf));
int plen;
const struct gprs_rlcmac_pdch *pdch;
@@ -1129,7 +1128,10 @@ void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, const struct gprs_rlcmac_dl_tbf
GSM_L1_BURST_TYPE_ACCESS_0);
if (plen >= 0) {
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_DL_TBF);
- pcu_l1if_tx_pch(bts, immediate_assignment, plen, pgroup);
+ if (the_pcu->pcu_if_version >= 0x0b)
+ pcu_l1if_tx_pch_dt(bts, immediate_assignment, plen, tbf->imsi(), tbf->tlli());
+ else
+ pcu_l1if_tx_pch(bts, immediate_assignment, plen, ms_paging_group(tbf_ms(tbf)));
}
bitvec_free(immediate_assignment);
diff --git a/src/gprs_pcu.h b/src/gprs_pcu.h
index a9e40ea6..ca52c30a 100644
--- a/src/gprs_pcu.h
+++ b/src/gprs_pcu.h
@@ -134,6 +134,8 @@ struct gprs_pcu {
struct si_cache *si_cache; /* ARFC+BSIC -> CGI PS cache */
struct osmo_timer_list update_stats_timer; /* Used to update some time_cc stats periodically */
+
+ uint8_t pcu_if_version;
};
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 6c4ed22f..14cc7783 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -294,6 +294,24 @@ void pcu_l1if_tx_pch(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, uint1
pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, sizeof(data));
}
+/* Send a block via the paging channel and require a confirmation by the receiving end */
+void pcu_l1if_tx_pch_dt(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, const char *imsi, uint32_t tlli)
+{
+ /* NOTE: This is in practice only used to transmit IMMEDIATE ASSIGNMENT messages through the paging channel and
+ * it is not guaranteed to work with other message types. The prepended TLLI will be used as an identifier in
+ * the confirmation message. */
+
+ struct gsm_pcu_if_pch_dt pch_dt;
+
+ pch_dt.tlli = tlli;
+ strcpy(pch_dt.imsi, imsi);
+
+ pch_dt.data[0] = (plen << 2) | 0x01;
+ bitvec_pack(block, pch_dt.data + 1);
+
+ pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH_DT, 0, 0, 0, (uint8_t*)&pch_dt, sizeof(pch_dt));
+}
+
int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key)
{
struct msgb *msg;
@@ -734,14 +752,22 @@ static int pcu_rx_info_ind(struct gprs_rlcmac_bts *bts, const struct gsm_pcu_if_
if (llist_count(&the_pcu->bts_list) > 1)
LOGP(DL1IF, LOGL_ERROR, "more than one BTS regsitered at this PCU. This PCU has only been tested with one BTS! OS#5930\n");
- if (info_ind->version != PCU_IF_VERSION) {
- fprintf(stderr, "PCU interface version number of BTS (%u) is "
- "different (%u).\nPlease re-compile!\n",
+ LOGP(DL1IF, LOGL_DEBUG, "Info indication received:\n");
+
+ /* NOTE: The classic way to confirm an IMMEDIATE assignment is to send the whole MAC block payload back to the
+ * PCU. So it is the MAC block itsself that serves a reference for the confirmation. This method has certain
+ * disadvantages so it was replaced with a method that uses the TLLI as a reference ("Direct TLLI"). This new
+ * method will replace the old one. The code that handles the old method will be removed in the foreseeable
+ * future. (see also OS#5927) */
+ if (info_ind->version == 0x0a) {
+ LOGP(DL1IF, LOGL_NOTICE, "PCUIF version 10 is deprecated. OS#5927\n");
+ } else if (info_ind->version != PCU_IF_VERSION) {
+ fprintf(stderr, "PCU interface version number of BTS/BSC (%u) is different (%u).\nPlease use a BTS/BSC with a compatble interface!\n",
info_ind->version, PCU_IF_VERSION);
exit(-1);
}
- LOGP(DL1IF, LOGL_DEBUG, "Info indication received:\n");
+ the_pcu->pcu_if_version = info_ind->version;
if (!(info_ind->flags & PCU_IF_FLAG_ACTIVE)) {
LOGP(DL1IF, LOGL_NOTICE, "BTS not available\n");
diff --git a/src/pcu_l1_if.h b/src/pcu_l1_if.h
index e7080d5a..1827d84c 100644
--- a/src/pcu_l1_if.h
+++ b/src/pcu_l1_if.h
@@ -149,6 +149,7 @@ void pcu_l1if_tx_ptcch(struct gprs_rlcmac_bts *bts,
void pcu_l1if_tx_agch(struct gprs_rlcmac_bts *bts, bitvec *block, int len);
void pcu_l1if_tx_pch(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, uint16_t pgroup);
+void pcu_l1if_tx_pch_dt(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, const char *imsi, uint32_t tlli);
#endif
#ifdef __cplusplus