aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-11-17 15:51:22 +0100
committerHarald Welte <laforge@gnumonks.org>2016-11-17 18:11:16 +0100
commitbe86e3cbe4f45e26093d669979f3b3d8b07ba82c (patch)
tree9b30fd0a112967217defb23952a75b72a3d40e94
parent7138ba5b08e0e4cd101d7f0ccc8686f532521f52 (diff)
WIP: PCU interface integration into BSC
This still has plenty of details to be ironed out. Change-Id: I44c8d84e5fb240af605483312dd5d1f86adbf758
-rw-r--r--openbsc/include/openbsc/Makefile.am2
-rw-r--r--openbsc/include/openbsc/debug.h1
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h4
-rw-r--r--openbsc/include/openbsc/pcu_if.h47
-rw-r--r--openbsc/src/libbsc/Makefile.am1
-rw-r--r--openbsc/src/libbsc/abis_rsl.c54
-rw-r--r--openbsc/src/libbsc/bsc_init.c21
-rw-r--r--openbsc/src/libbsc/pcu_sock.c214
-rw-r--r--openbsc/src/libcommon/debug.c5
9 files changed, 192 insertions, 157 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 5737a4bb1..9d842efb3 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -62,6 +62,8 @@ noinst_HEADERS = \
osmo_msc_data.h \
osmux.h \
paging.h \
+ pcu_if.h \
+ pcuif_proto.h \
rest_octets.h \
rrlp.h \
rs232.h \
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index ca3d4ad0d..8c0f3fa98 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -38,6 +38,7 @@ enum {
DRANAP,
DSUA,
DV42BIS,
+ DPCU,
Debug_LastEntry,
};
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 5fd7f5d29..6dfa7218e 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -43,6 +43,7 @@ enum gsm_chreq_reason_t {
GSM_CHREQ_REASON_PAG,
GSM_CHREQ_REASON_CALL,
GSM_CHREQ_REASON_LOCATION_UPD,
+ GSM_CHREQ_REASON_PBCH,
GSM_CHREQ_REASON_OTHER,
};
@@ -832,6 +833,9 @@ struct gsm_bts {
struct amr_multirate_conf mr_full;
struct amr_multirate_conf mr_half;
+ /* PCU socket state */
+ struct pcu_sock_state *pcu_state;
+
#endif /* ROLE_BSC */
void *role;
};
diff --git a/openbsc/include/openbsc/pcu_if.h b/openbsc/include/openbsc/pcu_if.h
index a020c050b..604d00636 100644
--- a/openbsc/include/openbsc/pcu_if.h
+++ b/openbsc/include/openbsc/pcu_if.h
@@ -3,23 +3,48 @@
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
+#include <osmocom/gsm/l1sap.h>
+
extern int pcu_direct;
-int pcu_tx_info_ind(void);
-int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
+struct pcu_sock_state {
+ struct gsm_network *net;
+ struct osmo_fd listen_bfd; /* fd for listen socket */
+ struct osmo_fd conn_bfd; /* fd for connection to lcr */
+ struct llist_head upqueue; /* queue for sending messages */
+};
+
+/* PCU relevant information has changed; Inform PCU (if connected) */
+void pcu_info_update(struct gsm_bts *bts);
+
+/* Forward rach indication to PCU */
+int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
+ uint8_t is_11bit, enum ph_burst_type burst_type);
+
+/* Forward timing intformation (frame number) to PCU */
+int pcu_tx_time_ind(struct gsm_bts *bts, uint32_t fn);
+
+
+int pcu_tx_rts_req(struct gsm_bts *bts, struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr);
-int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
+int pcu_tx_data_ind(struct gsm_bts *bts, struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, 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);
-int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
- uint8_t is_11bit, enum ph_burst_type burst_type);
-int pcu_tx_time_ind(uint32_t fn);
-int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
-int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
-int pcu_sock_init(const char *path);
-void pcu_sock_exit(void);
-bool pcu_connected(void);
+
+
+
+int pcu_tx_pag_req(struct gsm_bts *bts, const uint8_t *identity_lv, uint8_t chan_needed);
+int pcu_tx_pch_data_cnf(struct gsm_bts *bts, uint32_t fn, uint8_t *data, uint8_t len);
+
+/* Open connection to PCU */
+int pcu_sock_init(const char *path, struct gsm_bts *bts);
+
+/* Close connection to PCU */
+void pcu_sock_exit(struct gsm_bts *bts);
+
+/* Check if BTS has a PCU connection */
+bool pcu_connected(struct gsm_bts *bts);
#endif /* _PCU_IF_H */
diff --git a/openbsc/src/libbsc/Makefile.am b/openbsc/src/libbsc/Makefile.am
index 8c5381777..c0c43aa5f 100644
--- a/openbsc/src/libbsc/Makefile.am
+++ b/openbsc/src/libbsc/Makefile.am
@@ -35,6 +35,7 @@ libbsc_a_SOURCES = \
handover_decision.c \
handover_logic.c \
meas_rep.c \
+ pcu_sock.c \
rest_octets.c \
system_information.c \
e1_config.c \
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index 3e4d7cb9a..ce9e20eee 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -44,6 +44,7 @@
#include <osmocom/abis/e1_input.h>
#include <osmocom/gsm/rsl.h>
#include <osmocom/core/talloc.h>
+#include <openbsc/pcu_if.h>
#define RSL_ALLOC_SIZE 1024
#define RSL_ALLOC_HEADROOM 128
@@ -1245,6 +1246,12 @@ static int rsl_rx_chan_act_ack(struct msgb *msg)
send_lchan_signal(S_LCHAN_ACTIVATE_ACK, lchan, NULL);
+ /* Update bts attributes inside the PCU */
+ if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH ||
+ ts->pchan == GSM_PCHAN_TCH_F_PDCH ||
+ ts->pchan == GSM_PCHAN_PDCH)
+ pcu_info_update(ts->trx->bts);
+
return 0;
}
@@ -1715,6 +1722,45 @@ static int rsl_send_imm_ass_rej(struct gsm_bts *bts,
return rsl_imm_assign_cmd(bts, sizeof(*iar), (uint8_t *) iar);
}
+/* Handle packet channel rach requests */
+static int rsl_rx_pchan_rqd(struct msgb *msg, struct gsm_bts *bts)
+{
+ struct gsm48_req_ref *rqd_ref;
+ struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
+ rqd_ref = (struct gsm48_req_ref *) &rqd_hdr->data[1];
+ uint8_t ra = rqd_ref->ra;
+ uint8_t t1, t2, t3;
+ uint32_t fn;
+ uint8_t rqd_ta;
+ uint8_t is_11bit;
+
+ /* Bail if no PCU is connected */
+ if (!pcu_connected(bts)) {
+ LOGP(DRSL, LOGL_ERROR, "BTS %d PCU not availabe!\n",bts->nr);
+ return -EINVAL;
+ }
+
+ /* Process rach request and forward contained information to PCU */
+ if (ra == 0x7F) {
+ is_11bit = 1;
+
+ /* FIXME: Also handle 11 bit rach requests */
+ LOGP(DRSL, LOGL_ERROR, "BTS %d eleven bit access burst not supported yet!\n",bts->nr);
+ return -EINVAL;
+ } else {
+ is_11bit = 0;
+ t1 = rqd_ref->t1;
+ t2 = rqd_ref->t2;
+ t3 = rqd_ref->t3_low | (rqd_ref->t3_high << 3);
+ fn = (51 * ((t3-t2) % 26) + t3 + 51 * 26 * t1);
+
+ rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
+ }
+
+ return pcu_tx_rach_ind(bts, rqd_ta, ra, fn, is_11bit,
+ GSM_L1_BURST_TYPE_ACCESS_0);
+}
+
/* MS has requested a channel on the RACH */
static int rsl_rx_chan_rqd(struct msgb *msg)
{
@@ -1742,10 +1788,16 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
return -EINVAL;
rqd_ta = rqd_hdr->data[sizeof(struct gsm48_req_ref)+2];
+ /* Determine channel request cause code */
+ chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
+
+ /* Hanle PBCH related rach requests (in case of BSC-co-located-PCU */
+ if (chreq_reason == GSM_CHREQ_REASON_PBCH)
+ return rsl_rx_pchan_rqd(msg, bts);
+
/* determine channel type (SDCCH/TCH_F/TCH_H) based on
* request reference RA */
lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
- chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
rate_ctr_inc(&bts->network->bsc_ctrs->ctr[BSC_CTR_CHREQ_TOTAL]);
diff --git a/openbsc/src/libbsc/bsc_init.c b/openbsc/src/libbsc/bsc_init.c
index bf6e056a2..9ea085e1d 100644
--- a/openbsc/src/libbsc/bsc_init.c
+++ b/openbsc/src/libbsc/bsc_init.c
@@ -36,6 +36,8 @@
#include <openbsc/ipaccess.h>
#include <osmocom/gsm/sysinfo.h>
#include <openbsc/e1_config.h>
+#include <openbsc/pcu_if.h>
+#include <limits.h>
/* global pointer to the gsm network data structure */
extern struct gsm_network *bsc_gsmnet;
@@ -190,6 +192,10 @@ int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx)
return rc;
}
+ /* Make sure the PCU is aware (in case anything GPRS related has
+ * changed in SI */
+ pcu_info_update(bts);
+
return 0;
err_out:
LOGP(DRR, LOGL_ERROR, "Cannot generate SI%s for BTS %u: error <%s>,"
@@ -480,6 +486,8 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
{
struct gsm_bts *bts;
int rc;
+ char pcu_sock_path[PATH_MAX];
+ char pcu_sock_path_ending[PATH_MAX];
/* initialize our data structures */
bsc_gsmnet = gsm_network_init(tall_bsc_ctx, 1, 1, mncc_recv);
@@ -515,6 +523,19 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *),
LOGP(DNM, LOGL_FATAL, "Error enabling E1 input driver\n");
return rc;
}
+
+ strcpy(pcu_sock_path, PCU_SOCK_DEFAULT);
+ sprintf(pcu_sock_path_ending,"_%i", bts->nr);
+ if (bts->nr > 0)
+ strcat(pcu_sock_path, pcu_sock_path_ending);
+ rc = pcu_sock_init(pcu_sock_path, bts);
+
+ if (rc < 0) {
+ LOGP(DNM, LOGL_FATAL,
+ "PCU L1 socket failed for bts %i\n", bts->nr);
+ return rc;
+ }
}
+
return 0;
}
diff --git a/openbsc/src/libbsc/pcu_sock.c b/openbsc/src/libbsc/pcu_sock.c
index 62f18a783..ccc0e9a01 100644
--- a/openbsc/src/libbsc/pcu_sock.c
+++ b/openbsc/src/libbsc/pcu_sock.c
@@ -33,20 +33,18 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
-#include <osmo-bts/logging.h>
-#include <osmo-bts/gsm_data.h>
-#include <osmo-bts/pcu_if.h>
-#include <osmo-bts/pcuif_proto.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/rsl.h>
-#include <osmo-bts/signal.h>
-#include <osmo-bts/l1sap.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/gsm/l1sap.h>
-uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
+#include <openbsc/gsm_data.h>
+#include <openbsc/pcu_if.h>
+#include <openbsc/pcuif_proto.h>
+#include <openbsc/signal.h>
+#include <openbsc/debug.h>
-extern struct gsm_network bts_gsmnet;
+static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg);
+uint32_t trx_get_hlayer1(struct gsm_bts_trx *trx);
int pcu_direct = 0;
-static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0};
static const char *sapi_string[] = {
[PCU_IF_SAPI_RACH] = "RACH",
@@ -58,9 +56,6 @@ static const char *sapi_string[] = {
[PCU_IF_SAPI_PTCCH] = "PTCCH",
};
-static int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
-
-
static struct gsm_bts_trx *trx_by_nr(struct gsm_bts *bts, uint8_t trx_nr)
{
struct gsm_bts_trx *trx;
@@ -73,11 +68,11 @@ static struct gsm_bts_trx *trx_by_nr(struct gsm_bts *bts, uint8_t trx_nr)
return NULL;
}
-
/*
* PCU messages
*/
+/* Set up an message buffer to package an pcu interface message */
struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
{
struct msgb *msg;
@@ -86,6 +81,7 @@ struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
msg = msgb_alloc(sizeof(struct gsm_pcu_if), "pcu_sock_tx");
if (!msg)
return NULL;
+
msgb_put(msg, sizeof(struct gsm_pcu_if));
pcu_prim = (struct gsm_pcu_if *) msg->data;
pcu_prim->msg_type = msg_type;
@@ -94,6 +90,7 @@ struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
return msg;
}
+/* Helper function exclusivly used by pcu_if_signal_cb() */
static bool ts_should_be_pdch(struct gsm_bts_trx_ts *ts) {
if (ts->pchan == GSM_PCHAN_PDCH)
return true;
@@ -120,44 +117,42 @@ static bool ts_should_be_pdch(struct gsm_bts_trx_ts *ts) {
return false;
}
-int pcu_tx_info_ind(void)
+/* Send BTS properties to the PCU */
+static int pcu_tx_info_ind(struct gsm_bts *bts)
{
- struct gsm_network *net = &bts_gsmnet;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_info_ind *info_ind;
- struct gsm_bts *bts;
struct gprs_rlc_cfg *rlcc;
struct gsm_bts_gprs_nsvc *nsvc;
struct gsm_bts_trx *trx;
struct gsm_bts_trx_ts *ts;
int i, j;
- LOGP(DPCU, LOGL_INFO, "Sending info\n");
+ printf("======================= PCU UPDATE! =========================\n");
+
+ OSMO_ASSERT(bts);
+ OSMO_ASSERT(bts->network);
+
+ LOGP(DPCU, LOGL_INFO, "Sending info for BTS %d\n",bts->nr);
- /* FIXME: allow multiple BTS */
- bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
rlcc = &bts->gprs.cell.rlc_cfg;
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;
-
- if (avail_lai && avail_nse && avail_cell && avail_nsvc[0]) {
- info_ind->flags |= PCU_IF_FLAG_ACTIVE;
- LOGP(DPCU, LOGL_INFO, "BTS is up\n");
- } else
- LOGP(DPCU, LOGL_INFO, "BTS is down\n");
+ info_ind->flags |= PCU_IF_FLAG_ACTIVE;
if (pcu_direct)
info_ind->flags |= PCU_IF_FLAG_SYSMO;
/* RAI */
- info_ind->mcc = net->mcc;
- info_ind->mnc = net->mnc;
+ info_ind->mcc = bts->network->country_code;
+ info_ind->mnc = bts->network->network_code;
info_ind->lac = bts->location_area_code;
info_ind->rac = bts->gprs.rac;
@@ -228,7 +223,6 @@ int pcu_tx_info_ind(void)
break;
info_ind->trx[i].pdch_mask = 0;
info_ind->trx[i].arfcn = trx->arfcn;
- info_ind->trx[i].hlayer1 = trx_get_hlayer1(trx);
for (j = 0; j < 8; j++) {
ts = &trx->ts[j];
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
@@ -245,76 +239,22 @@ int pcu_tx_info_ind(void)
}
}
- return pcu_sock_send(net, msg);
+ return pcu_sock_send(bts, msg);
}
-static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal,
- void *hdlr_data, void *signal_data)
+void pcu_info_update(struct gsm_bts *bts)
{
- struct gsm_network *net = &bts_gsmnet;
- struct gsm_bts_gprs_nsvc *nsvc;
- struct gsm_bts *bts;
- struct gsm48_system_information_type_3 *si3;
- int id;
-
- if (subsys != SS_GLOBAL)
- return -EINVAL;
-
- switch(signal) {
- case S_NEW_SYSINFO:
- bts = signal_data;
- if (!(bts->si_valid & (1 << SYSINFO_TYPE_3)))
- break;
- si3 = (struct gsm48_system_information_type_3 *)
- bts->si_buf[SYSINFO_TYPE_3];
- net->mcc = ((si3->lai.digits[0] & 0x0f) << 8)
- | (si3->lai.digits[0] & 0xf0)
- | (si3->lai.digits[1] & 0x0f);
- net->mnc = ((si3->lai.digits[2] & 0x0f) << 8)
- | (si3->lai.digits[2] & 0xf0)
- | ((si3->lai.digits[1] & 0xf0) >> 4);
- if ((net->mnc & 0x00f) == 0x00f)
- net->mnc >>= 4;
- bts->location_area_code = ntohs(si3->lai.lac);
- bts->cell_identity = si3->cell_identity;
- avail_lai = 1;
- break;
- case S_NEW_NSE_ATTR:
- bts = signal_data;
- avail_nse = 1;
- break;
- case S_NEW_CELL_ATTR:
- bts = signal_data;
- avail_cell = 1;
- break;
- case S_NEW_NSVC_ATTR:
- nsvc = signal_data;
- id = nsvc->id;
- if (id < 0 || id > 1)
- return -EINVAL;
- avail_nsvc[id] = 1;
- break;
- case S_NEW_OP_STATE:
- break;
- default:
- return -EINVAL;
- }
-
- /* If all infos have been received, of if one info is updated after
- * all infos have been received, transmit info update. */
- if (avail_lai && avail_nse && avail_cell && avail_nsvc[0])
- pcu_tx_info_ind();
- return 0;
+ if (pcu_connected(bts))
+ pcu_tx_info_ind(bts);
}
-int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
+int pcu_tx_rts_req(struct gsm_bts *bts, struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
uint16_t arfcn, uint8_t block_nr)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_rts_req *rts_req;
- struct gsm_bts *bts = ts->trx->bts;
LOGP(DPCU, LOGL_DEBUG, "Sending rts request: is_ptcch=%d arfcn=%d "
"block=%d\n", is_ptcch, arfcn, block_nr);
@@ -332,17 +272,16 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
rts_req->ts_nr = ts->nr;
rts_req->block_nr = block_nr;
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
-int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
+int pcu_tx_data_ind(struct gsm_bts *bts, struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, 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: is_ptcch=%d arfcn=%d "
"block=%d data=%s\n", is_ptcch, arfcn, block_nr,
@@ -368,9 +307,10 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
memcpy(data_ind->data, data, len);
data_ind->len = len;
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
+/* Forward rach indication to PCU */
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
uint8_t is_11bit, enum ph_burst_type burst_type)
{
@@ -394,10 +334,10 @@ int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
rach_ind->is_11bit = is_11bit;
rach_ind->burst_type = burst_type;
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
-int pcu_tx_time_ind(uint32_t fn)
+int pcu_tx_time_ind(struct gsm_bts *bts, uint32_t fn)
{
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
@@ -416,12 +356,14 @@ int pcu_tx_time_ind(uint32_t fn)
time_ind->fn = fn;
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
-int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed)
+/* Forward paging information to PCU */
+int pcu_tx_pag_req(struct gsm_bts *bts, const uint8_t *identity_lv,
+ uint8_t chan_needed)
{
- struct pcu_sock_state *state = bts_gsmnet.pcu_state;
+ struct pcu_sock_state *state = bts->pcu_state;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_pag_req *pag_req;
@@ -449,20 +391,15 @@ int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed)
pag_req->chan_needed = chan_needed;
memcpy(pag_req->identity_lv, identity_lv, identity_lv[0] + 1);
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
-int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len)
+int pcu_tx_pch_data_cnf(struct gsm_bts *bts, uint32_t fn, uint8_t *data, uint8_t len)
{
- struct gsm_network *net = &bts_gsmnet;
- struct gsm_bts *bts;
struct msgb *msg;
struct gsm_pcu_if *pcu_prim;
struct gsm_pcu_if_data *data_cnf;
- /* FIXME: allow multiple BTS */
- bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
-
LOGP(DPCU, LOGL_INFO, "Sending PCH confirm\n");
msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_CNF, bts->nr);
@@ -476,7 +413,7 @@ int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len)
memcpy(data_cnf->data, data, len);
data_cnf->len = len;
- return pcu_sock_send(&bts_gsmnet, msg);
+ return pcu_sock_send(bts, msg);
}
static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
@@ -502,7 +439,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
} else {
bts->si_valid &= ~(1 << SYSINFO_TYPE_13);
}
- osmo_signal_dispatch(SS_GLOBAL, S_NEW_SYSINFO, bts);
+ // osmo_signal_dispatch(SS_GLOBAL, S_NEW_SYSINFO, bts);
break;
case PCU_IF_SAPI_PCH:
if (msg_type == PCU_IF_MSG_PAG_REQ) {
@@ -512,8 +449,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
} else {
struct gsm_bts_role_bts *btsb = bts->role;
- paging_add_imm_ass(btsb->paging_state, data_req->data,
- data_req->len);
+ printf("paging_add_imm_ass(btsb->paging_state, data_req->data,data_req->len);\n");
}
break;
case PCU_IF_SAPI_AGCH:
@@ -524,7 +460,8 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
}
msg->l3h = msgb_put(msg, data_req->len);
memcpy(msg->l3h, data_req->data, data_req->len);
- if (bts_agch_enqueue(bts, msg) < 0) {
+
+ if (rsl_imm_assign_cmd(bts, msg->len, msg->data)) {
msgb_free(msg);
rc = -EIO;
}
@@ -540,8 +477,8 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
}
ts = &trx->ts[data_req->ts_nr];
is_ptcch = (data_req->sapi == PCU_IF_SAPI_PTCCH);
- rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,
- data_req->block_nr, data_req->data, data_req->len);
+ printf("rc = l1sap_pdch_req(ts, is_ptcch, data_req->fn, data_req->arfcn,data_req->block_nr, data_req->data, data_req->len);\n");
+ rc = -EINVAL;
break;
default:
LOGP(DPCU, LOGL_ERROR, "Received PCU data request with "
@@ -552,8 +489,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
return rc;
}
-static int pcu_rx_act_req(struct gsm_bts *bts,
- struct gsm_pcu_if_act_req *act_req)
+static int pcu_rx_act_req(struct gsm_bts *bts, struct gsm_pcu_if_act_req *act_req)
{
struct gsm_bts_trx *trx;
struct gsm_lchan *lchan;
@@ -567,7 +503,7 @@ static int pcu_rx_act_req(struct gsm_bts *bts,
return -EINVAL;
lchan = trx->ts[act_req->ts_nr].lchan;
- lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
+// lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
if (lchan->type != GSM_LCHAN_PDTCH) {
LOGP(DPCU, LOGL_ERROR,
"%s request, but lchan is not of type PDTCH (is %s)\n",
@@ -576,9 +512,9 @@ static int pcu_rx_act_req(struct gsm_bts *bts,
return -EINVAL;
}
if (act_req->activate)
- l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL);
+ printf("l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL);\n");
else
- l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan));
+ printf("l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan));\n");
return 0;
}
@@ -613,16 +549,9 @@ static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
* PCU socket interface
*/
-struct pcu_sock_state {
- struct gsm_network *net;
- struct osmo_fd listen_bfd; /* fd for listen socket */
- struct osmo_fd conn_bfd; /* fd for connection to lcr */
- struct llist_head upqueue; /* queue for sending messages */
-};
-
-static int pcu_sock_send(struct gsm_network *net, struct msgb *msg)
+static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg)
{
- struct pcu_sock_state *state = net->pcu_state;
+ struct pcu_sock_state *state = bts->pcu_state;
struct osmo_fd *conn_bfd;
struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msg->data;
@@ -682,9 +611,8 @@ static void pcu_sock_close(struct pcu_sock_state *state)
ts = &trx->ts[j];
if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED
&& ts->pchan == GSM_PCHAN_PDCH) {
- ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
- l1sap_chan_rel(trx,
- gsm_lchan2chan_nr(ts->lchan));
+// ts->lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
+ printf("l1sap_chan_rel(trx,gsm_lchan2chan_nr(ts->lchan));\n");
}
}
}
@@ -836,13 +764,11 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
LOGP(DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n");
- /* send current info */
- pcu_tx_info_ind();
-
return 0;
}
-int pcu_sock_init(const char *path)
+/* Open connection to PCU */
+int pcu_sock_init(const char *path, struct gsm_bts *bts)
{
struct pcu_sock_state *state;
struct osmo_fd *bfd;
@@ -853,7 +779,7 @@ int pcu_sock_init(const char *path)
return -ENOMEM;
INIT_LLIST_HEAD(&state->upqueue);
- state->net = &bts_gsmnet;
+ state->net = bts->network;
state->conn_bfd.fd = -1;
bfd = &state->listen_bfd;
@@ -880,22 +806,19 @@ int pcu_sock_init(const char *path)
return rc;
}
- osmo_signal_register_handler(SS_GLOBAL, pcu_if_signal_cb, NULL);
-
- bts_gsmnet.pcu_state = state;
-
+ bts->pcu_state = state;
return 0;
}
-void pcu_sock_exit(void)
+/* Close connection to PCU */
+void pcu_sock_exit(struct gsm_bts *bts)
{
- struct pcu_sock_state *state = bts_gsmnet.pcu_state;
+ struct pcu_sock_state *state = bts->pcu_state;
struct osmo_fd *bfd, *conn_bfd;
if (!state)
return;
- osmo_signal_unregister_handler(SS_GLOBAL, pcu_if_signal_cb, NULL);
conn_bfd = &state->conn_bfd;
if (conn_bfd->fd > 0)
pcu_sock_close(state);
@@ -903,12 +826,13 @@ void pcu_sock_exit(void)
close(bfd->fd);
osmo_fd_unregister(bfd);
talloc_free(state);
- bts_gsmnet.pcu_state = NULL;
+ bts->pcu_state = NULL;
}
-bool pcu_connected(void) {
- struct gsm_network *net = &bts_gsmnet;
- struct pcu_sock_state *state = net->pcu_state;
+/* Check if BTS has a PCU connection */
+bool pcu_connected(struct gsm_bts *bts)
+{
+ struct pcu_sock_state *state = bts->pcu_state;
if (!state)
return false;
diff --git a/openbsc/src/libcommon/debug.c b/openbsc/src/libcommon/debug.c
index cf5beeb44..86d7cd2c8 100644
--- a/openbsc/src/libcommon/debug.c
+++ b/openbsc/src/libcommon/debug.c
@@ -175,6 +175,11 @@ static const struct log_info_cat default_categories[] = {
.description = "SCCP User Adaptation Protocol",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
+ [DPCU] = {
+ .name = "DPCU",
+ .description = "PCU Interface",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
};
enum log_filter {