dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/30749 )
Change subject: WIP Ericsson GPRS support ......................................................................
WIP Ericsson GPRS support
Change-Id: If96b3f1e26a7206fcd2658b6faf6afe556cfbb14 --- M include/osmocom/bsc/abis_rsl.h M include/osmocom/bsc/pcuif_proto.h M src/osmo-bsc/abis_rsl.c M src/osmo-bsc/pcu_sock.c 4 files changed, 348 insertions(+), 38 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/49/30749/1
diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h index dcae348..b3aef7c 100644 --- a/include/osmocom/bsc/abis_rsl.h +++ b/include/osmocom/bsc/abis_rsl.h @@ -66,6 +66,9 @@
/* Ericcson vendor specific RSL extensions */ int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val); +int rsl_ericsson_imm_assign_via_pch_cmd(struct gsm_bts *bts, uint8_t len, + uint8_t *val, uint32_t tlli, + uint8_t pag_grp);
/* Siemens vendor-specific RSL extensions */ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci); diff --git a/include/osmocom/bsc/pcuif_proto.h b/include/osmocom/bsc/pcuif_proto.h index fef0f88..78f56c9 100644 --- a/include/osmocom/bsc/pcuif_proto.h +++ b/include/osmocom/bsc/pcuif_proto.h @@ -2,6 +2,7 @@ #define _PCUIF_PROTO_H
#include <osmocom/gsm/l1sap.h> +#include <osmocom/abis/e1_input.h> #include <arpa/inet.h>
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts" @@ -9,6 +10,7 @@ #define PCU_IF_VERSION 0x0a #define TXT_MAX_LEN 128
+ /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ #define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */ @@ -19,6 +21,7 @@ #define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */ #define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */ #define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */ +#define PCU_IF_MSG_E1_CCU_IND 0x33 /* retrieve E1 CCU comm. parameters */ #define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */ #define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */ #define PCU_IF_MSG_INTERF_IND 0x53 /* interference report */ @@ -257,6 +260,13 @@ } cgi_ps; } __attribute__ ((packed));
+/* E1 CCU connection parameters */ +struct gsm_pcu_if_e1_ccu_ind { + uint8_t pdch_trx_no; + uint8_t pdch_ts; + struct gsm_e1_subslot e1_link; +} __attribute__ ((packed)); + struct gsm_pcu_if { /* context based information */ uint8_t msg_type; /* message type */ @@ -273,6 +283,7 @@ struct gsm_pcu_if_rach_ind rach_ind; struct gsm_pcu_if_txt_ind txt_ind; struct gsm_pcu_if_info_ind info_ind; + struct gsm_pcu_if_e1_ccu_ind e1_ccu_ind; struct gsm_pcu_if_act_req act_req; struct gsm_pcu_if_time_ind time_ind; struct gsm_pcu_if_pag_req pag_req; diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c index 3d18447..b933442 100644 --- a/src/osmo-bsc/abis_rsl.c +++ b/src/osmo-bsc/abis_rsl.c @@ -978,6 +978,24 @@ return abis_rsl_sendmsg(msg); }
+/* Chapter 8.5.6 Immediate Assignment Command (with Ericcson vendor specific RSL extension) */ +int rsl_ericsson_imm_assign_via_pch_cmd(struct gsm_bts *bts, uint8_t len, + uint8_t *val, uint32_t tlli, + uint8_t pag_grp) +{ + struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val); + + /* Append ericsson propritary paging group field */ + msgb_put_u8(msg, RSL_IE_ERIC_PAGING_GROUP); + msgb_put_u8(msg, pag_grp); + + /* Append ericsson propritary mobile identity field (see also comment above) */ + msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID); + msgb_put_u32(msg, tlli); + + return abis_rsl_sendmsg(msg); +} + /* Send Siemens specific MS RF Power Capability Indication */ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci) { diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c index 81198bd..659cd8e 100644 --- a/src/osmo-bsc/pcu_sock.c +++ b/src/osmo-bsc/pcu_sock.c @@ -33,6 +33,7 @@ #include <osmocom/core/logging.h> #include <osmocom/gsm/l1sap.h> #include <osmocom/gsm/gsm0502.h> +#include <osmocom/bsc/abis_nm.h>
#include <osmocom/bsc/gsm_data.h> #include <osmocom/bsc/pcu_if.h> @@ -44,8 +45,10 @@ #include <osmocom/bsc/bts.h> #include <osmocom/bsc/bts_sm.h>
+#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args) + static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg); -uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); +//uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx); int pcu_direct = 1;
static const char *sapi_string[] = { @@ -93,6 +96,13 @@ return msg; }
+static bool ts_should_be_pdch(const struct gsm_bts_trx_ts *ts) +{ + if (ts->pchan_is == GSM_PCHAN_PDCH) + return true; + return false; +} + /* Fill the frequency hopping parameter */ static void info_ind_fill_fhp(struct gsm_pcu_if_info_trx_ts *ts_info, const struct gsm_bts_trx_ts *ts) @@ -105,6 +115,51 @@ ts_info->ma_bit_len = ts->hopping.ma_len * 8 - ts->hopping.ma.cur_bit; }
+static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info, + const struct gsm_bts_trx *trx) +{ + unsigned int tn; + + trx_info->pdch_mask = 0; + trx_info->arfcn = trx->arfcn; + trx_info->hlayer1 = 0x2342; + +#if 0 + if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED || + trx->mo.nm_state.administrative != NM_STATE_UNLOCKED) + { + LOGPTRX(trx, DPCU, LOGL_INFO, "unavailable for PCU (op=%s adm=%s)\n", + abis_nm_opstate_name(trx->mo.nm_state.operational), + abis_nm_admin_name(trx->mo.nm_state.administrative)); + return; + } +#endif + + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (!ts_should_be_pdch(ts)) + continue; + + trx_info->pdch_mask |= (1 << tn); + trx_info->ts[tn].tsc = ts->tsc; + + if (ts->hopping.enabled) + info_ind_fill_fhp(&trx_info->ts[tn], ts); + + LOGPTRX(trx, DPCU, LOGL_INFO, "PDCH on ts=%u is available " + "(tsc=%u ", ts->nr, trx_info->ts[tn].tsc); + if (ts->hopping.enabled) { + LOGPC(DPCU, LOGL_INFO, "hopping=yes hsn=%u maio=%u ma_bit_len=%u)\n", + ts->hopping.hsn, ts->hopping.maio, trx_info->ts[tn].ma_bit_len); + } else { + LOGPC(DPCU, LOGL_INFO, "hopping=no arfcn=%u)\n", trx->arfcn); + } + } +} + /* Send BTS properties to the PCU */ static int pcu_tx_info_ind(struct gsm_bts *bts) { @@ -115,13 +170,14 @@ struct gsm_bts_sm *bts_sm; struct gsm_gprs_nsvc *nsvc; struct gsm_bts_trx *trx; - struct gsm_bts_trx_ts *ts; - int i, tn; + int i;
OSMO_ASSERT(bts); OSMO_ASSERT(bts->network); OSMO_ASSERT(bts->site_mgr);
+ LOGP(DPCU, LOGL_INFO, "Sending info\n"); + bts_sm = bts->site_mgr;
LOGP(DPCU, LOGL_INFO, "Sending info for BTS %d\n",bts->nr); @@ -131,7 +187,6 @@ msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr); if (!msg) return -ENOMEM; - pcu_prim = (struct gsm_pcu_if *) msg->data; info_ind = &pcu_prim->u.info_ind; info_ind->version = PCU_IF_VERSION; @@ -140,6 +195,7 @@ if (pcu_direct) info_ind->flags |= PCU_IF_FLAG_SYSMO;
+ info_ind->bsic = bts->bsic; /* RAI */ info_ind->mcc = bts->network->plmn.mcc; info_ind->mnc = bts->network->plmn.mnc; @@ -194,9 +250,9 @@ if (rlcc->cs_mask & (1 << GPRS_MCS9)) info_ind->flags |= PCU_IF_FLAG_MCS9; } - /* TODO: isn't dl_tbf_ext wrong?: * 10 and no ntohs */ + /* FIXME: isn't dl_tbf_ext wrong?: * 10 and no ntohs */ info_ind->dl_tbf_ext = rlcc->parameter[T_DL_TBF_EXT]; - /* TODO: isn't ul_tbf_ext wrong?: * 10 and no ntohs */ + /* FIXME: isn't ul_tbf_ext wrong?: * 10 and no ntohs */ info_ind->ul_tbf_ext = rlcc->parameter[T_UL_TBF_EXT]; info_ind->initial_cs = rlcc->initial_cs; info_ind->initial_mcs = rlcc->initial_mcs; @@ -211,14 +267,14 @@ case AF_INET: info_ind->address_type[i] = PCU_IF_ADDR_TYPE_IPV4; info_ind->remote_ip[i].v4 = nsvc->remote.u.sin.sin_addr; - info_ind->remote_port[i] = nsvc->remote.u.sin.sin_port; + info_ind->remote_port[i] = ntohs(nsvc->remote.u.sin.sin_port); break; case AF_INET6: info_ind->address_type[i] = PCU_IF_ADDR_TYPE_IPV6; memcpy(&info_ind->remote_ip[i].v6, &nsvc->remote.u.sin6.sin6_addr, sizeof(struct in6_addr)); - info_ind->remote_port[i] = nsvc->remote.u.sin6.sin6_port; + info_ind->remote_port[i] = ntohs(nsvc->remote.u.sin6.sin6_port); break; default: info_ind->address_type[i] = PCU_IF_ADDR_TYPE_UNSPEC; @@ -230,40 +286,126 @@ trx = gsm_bts_trx_num(bts, i); if (!trx) continue; - info_ind->trx[i].hlayer1 = 0x2342; - info_ind->trx[i].pdch_mask = 0; - info_ind->trx[i].arfcn = trx->arfcn; - for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { - ts = &trx->ts[tn]; - if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED || - ts->pchan_is != GSM_PCHAN_PDCH) - continue; - - info_ind->trx[i].pdch_mask |= (1 << tn); - info_ind->trx[i].ts[tn].tsc = - (ts->tsc >= 0) ? ts->tsc : bts->bsic & 7; - - if (ts->hopping.enabled) - info_ind_fill_fhp(&info_ind->trx[i].ts[tn], ts); - - LOGP(DPCU, LOGL_INFO, "trx=%d ts=%d: PDCH is available " - "(tsc=%u ", trx->nr, ts->nr, info_ind->trx[i].ts[tn].tsc); - if (ts->hopping.enabled) - LOGPC(DPCU, LOGL_INFO, "hopping=yes hsn=%u maio=%u ma_bit_len=%u)\n", - ts->hopping.hsn, ts->hopping.maio, trx->ts[tn].hopping.ma.data_len - trx->ts[tn].hopping.ma.cur_bit); - else - LOGPC(DPCU, LOGL_INFO, "hopping=no arfcn=%u)\n", trx->arfcn); + if (trx->nr >= ARRAY_SIZE(info_ind->trx)) { + LOGPTRX(trx, DPCU, LOGL_NOTICE, "PCU interface (version %u) " + "cannot handle more than %zu transceivers => skipped\n", + PCU_IF_VERSION, ARRAY_SIZE(info_ind->trx)); + continue; } + info_ind_fill_trx(&info_ind->trx[trx->nr], trx); }
return pcu_sock_send(bts, msg); }
+static int pcu_tx_e1_ccu_ind(struct gsm_bts *bts) +{ + struct msgb *msg; + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_e1_ccu_ind *e1_ccu_ind; + int i; + int k; + struct gsm_bts_trx *trx; + struct gsm_bts_trx_ts *ts; + int rc; + + OSMO_ASSERT(bts); + OSMO_ASSERT(bts->network); + OSMO_ASSERT(bts->site_mgr); + + for (i = 0; i < PCU_IF_NUM_TRX; i++) { + trx = gsm_bts_trx_num(bts, i); + if (!trx) + continue; + if (trx->nr >= PCU_IF_NUM_TRX) { + LOGPTRX(trx, DPCU, LOGL_NOTICE, "PCU interface (version %u) " + "cannot handle more than %u transceivers => skipped\n", + PCU_IF_VERSION, PCU_IF_NUM_TRX); + continue; + } + + for (k = 0; k < 8; k++) { + ts = &trx->ts[k]; + + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (!ts_should_be_pdch(ts)) + continue; + + msg = pcu_msgb_alloc(PCU_IF_MSG_E1_CCU_IND, bts->nr); + if (!msg) + return -ENOMEM; + pcu_prim = (struct gsm_pcu_if *)msg->data; + e1_ccu_ind = &pcu_prim->u.e1_ccu_ind; + e1_ccu_ind->pdch_ts = ts->nr; + e1_ccu_ind->pdch_trx_no = trx->nr; + memcpy(&e1_ccu_ind->e1_link, &ts->e1_link, sizeof(e1_ccu_ind->e1_link)); + + LOGP(DPCU, LOGL_INFO, "Sending E1 CCU info for BTS %d, TRX %d, TS %d\n", bts->nr, + e1_ccu_ind->pdch_trx_no, e1_ccu_ind->pdch_ts); + + rc = pcu_sock_send(bts, msg); + if (rc < 0) + return -EINVAL; + } + } + + return 0; +} + /* Allow test to overwrite it */ __attribute__((weak)) void pcu_info_update(struct gsm_bts *bts) { - if (pcu_connected(bts)) + if (pcu_connected(bts)) { + /* In cases where the CCU is connected via an E1 line, we + * transmit the connection parameters for the PDCH before + * we announce the other BTS related parameters. */ + pcu_tx_e1_ccu_ind(bts); + pcu_tx_info_ind(bts); + } +} + +int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len, + int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual) +{ + struct msgb *msg; + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_data *data_ind; + struct gsm_bts *bts = ts->trx->bts; + + LOGP(DPCU, LOGL_DEBUG, "Sending data indication: sapi=%s arfcn=%d block=%d data=%s\n", + sapi_string[sapi], arfcn, block_nr, osmo_hexdump(data, len)); + +// TODO: Do we care? We are not using the pcu_sock for air interface traffic here +// if (lqual < bts->min_qual_norm) { +// LOGP(DPCU, LOGL_DEBUG, "Link quality %"PRId16" is below threshold %d, dropping packet\n", +// lqual, bts->min_qual_norm); +// return 0; +// } + + msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr); + if (!msg) + return -ENOMEM; + pcu_prim = (struct gsm_pcu_if *) msg->data; + data_ind = &pcu_prim->u.data_ind; + + data_ind->sapi = sapi; + data_ind->rssi = rssi; + data_ind->fn = fn; + data_ind->arfcn = arfcn; + data_ind->trx_nr = ts->trx->nr; + data_ind->ts_nr = ts->nr; + data_ind->block_nr = block_nr; + data_ind->ber10k = ber10k; + data_ind->ta_offs_qbits = bto; + data_ind->lqual_cb = lqual; + if (len) + memcpy(data_ind->data, data, len); + data_ind->len = len; + + return pcu_sock_send(bts, msg); }
/* Forward rach indication to PCU */ @@ -343,6 +485,7 @@ rc = -EINVAL; break; } + LOGP(DPCU, LOGL_ERROR, "PCU Sends paging " "request type %02x (chan_needed=%02x, mi=%s)\n", p1->msg_type, chan_needed, osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); @@ -370,6 +513,27 @@ return rc; }
+/* Helper function for pcu_rx_data_req() to extract paging group info */ +static uint8_t extract_paging_group(struct gsm_bts *bts, uint8_t *data) +{ + char imsi_digit_buf[4]; + uint8_t pag_grp; + + /* the first three bytes are the last three digits of + * the IMSI, which we need to compute the paging group */ + imsi_digit_buf[0] = data[0]; + imsi_digit_buf[1] = data[1]; + imsi_digit_buf[2] = data[2]; + imsi_digit_buf[3] = '\0'; + + pag_grp = gsm0502_calc_paging_group(&bts->si_common.chan_desc, + str_to_imsi(imsi_digit_buf)); + + LOGP(DPCU, LOGL_DEBUG, "Calculating paging group: imsi_digit_buf=%s ==> pag_grp=0x%02x\n", imsi_digit_buf, pag_grp); + + return pag_grp; +} + static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, struct gsm_pcu_if_data *data_req) { @@ -415,22 +579,26 @@ /* DT = direct tlli. A tlli is prefixed */
if (data_req->len < 5) { - LOGP(DPCU, LOGL_ERROR, "Received PCU data request with " - "invalid/small length %d\n", data_req->len); + LOGP(DPCU, LOGL_ERROR, "Received PCU data request with invalid/small length %d\n", + data_req->len); break; } memcpy(&tlli, data_req->data, 4); + pag_grp = extract_paging_group(bts, data_req->data + 4);
- msg = msgb_alloc(data_req->len - 4, "pcu_agch"); + msg = msgb_alloc(data_req->len - 7, "pcu_agch"); if (!msg) { rc = -ENOMEM; break; } - msg->l3h = msgb_put(msg, data_req->len - 4); - memcpy(msg->l3h, data_req->data + 4, data_req->len - 4); + msg->l3h = msgb_put(msg, data_req->len - 7); + memcpy(msg->l3h, data_req->data + 7, data_req->len - 7); + + LOGP(DPCU, LOGL_DEBUG, "PCU Sends immediate assignment via PCH (tlli=0x%08x, pag_grp=0x%02x)\n", + tlli, pag_grp);
if (bts->type == GSM_BTS_TYPE_RBS2000) - rc = rsl_ericsson_imm_assign_cmd(bts, tlli, msg->len, msg->data); + rc = rsl_ericsson_imm_assign_via_pch_cmd(bts, msg->len, msg->data, tlli, pag_grp); else rc = rsl_imm_assign_cmd(bts, msg->len, msg->data);
@@ -448,6 +616,106 @@ return rc; }
+int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, + bool enable) +{ + /* the SI is per-BTS so it doesn't matter which TRX we use */ + struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, 0); + + uint8_t si_buf[GSM_MACBLOCK_LEN]; + uint8_t len; + int rc; + + if (enable) { + memcpy(si_buf, GSM_BTS_SI(bts, si_type), GSM_MACBLOCK_LEN); + len = GSM_MACBLOCK_LEN; + LOGP(DPCU, LOGL_DEBUG, "Updating SI%s to PCU: %s\n", + get_value_string(osmo_sitype_strs, si_type), + osmo_hexdump_nospc(si_buf, GSM_MACBLOCK_LEN)); + } else { + si_buf[0] = si_type; + len = 1; + + /* Note: SI13 is the only system information type that is revked + * by just sending a completely empty message. This is due to + * historical reasons */ + if (si_type != SYSINFO_TYPE_13) + len = 0; + + LOGP(DPCU, LOGL_DEBUG, "Revoking SI%s from PCU\n", + get_value_string(osmo_sitype_strs, si_buf[0])); + } + + /* The low-level data like FN, ARFCN etc will be ignored but we have to + * set lqual high enough to bypass the check at lower levels */ + rc = pcu_tx_data_ind(&trx->ts[0], PCU_IF_SAPI_BCCH, 0, 0, 0, si_buf, len, + 0, 0, 0, INT16_MAX); + if (rc < 0) + LOGP(DPCU, LOGL_NOTICE, "Failed to send SI%s to PCU: rc=%d\n", + get_value_string(osmo_sitype_strs, si_type), rc); + + return rc; +} + +static int pcu_tx_si_all(struct gsm_bts *bts) +{ + const enum osmo_sysinfo_type si_types[] = + { SYSINFO_TYPE_1, SYSINFO_TYPE_2, SYSINFO_TYPE_3, SYSINFO_TYPE_13 }; + unsigned int i; + int rc = 0; + + for (i = 0; i < ARRAY_SIZE(si_types); i++) { + if (GSM_BTS_HAS_SI(bts, si_types[i])) { + rc = pcu_tx_si(bts, si_types[i], true); + if (rc < 0) + return rc; + } else { + LOGP(DPCU, LOGL_INFO, + "SI%s is not available on PCU connection\n", + get_value_string(osmo_sitype_strs, si_types[i])); + } + } + + return 0; +} + +static int pcu_rx_txt_ind(struct gsm_bts *bts, + struct gsm_pcu_if_txt_ind *txt) +{ + int rc; + + switch (txt->type) { + case PCU_VERSION: + LOGP(DPCU, LOGL_INFO, "OsmoPCU version %s connected\n", + txt->text); +//TODO: can we somehow regenerate the si restoctets or can we make the BTS to do so? +// probably regeneration of the si is not even needed since its different with ericsson anyway +// oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_CEASED, OSMO_EVT_PCU_VERS, txt->text); +// osmo_strlcpy(bts->pcu_version, txt->text, MAX_VERSION_LENGTH); + + /* patch SI to advertise GPRS, *if* the SI sent by BSC said so */ +// regenerate_si3_restoctets(bts); +// regenerate_si4_restoctets(bts); + + rc = pcu_tx_si_all(bts); + if (rc < 0) + return -EINVAL; + + break; + case PCU_OML_ALERT: +//TODO: Make BSC aware of this event locally +// oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_INDETERMINATE, OSMO_EVT_EXT_ALARM, +// txt->text); + break; + default: + LOGP(DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n", + txt->type); + return -EINVAL; + } + + return 0; +} + #define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \ do { \ size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \ @@ -472,6 +740,16 @@ CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.data_req); rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req); break; + case PCU_IF_MSG_TXT_IND: + CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.txt_ind); + rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind); + break; + case PCU_IF_SAPI_AGCH_DT: + printf("============> GOT PCU_IF_SAPI_AGCH_DT, but don't know what to do with it!\n"); + break; + case PCU_IF_MSG_ACT_REQ: + printf("============> GOT PCU_IF_MSG_ACT_REQ, but don't know what to do with it!\n"); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknown PCU msg type %d\n", msg_type);