diff options
author | Harald Welte <laforge@gnumonks.org> | 2016-11-17 15:51:22 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2016-11-17 18:11:16 +0100 |
commit | be86e3cbe4f45e26093d669979f3b3d8b07ba82c (patch) | |
tree | 9b30fd0a112967217defb23952a75b72a3d40e94 | |
parent | 7138ba5b08e0e4cd101d7f0ccc8686f532521f52 (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.am | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/debug.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data_shared.h | 4 | ||||
-rw-r--r-- | openbsc/include/openbsc/pcu_if.h | 47 | ||||
-rw-r--r-- | openbsc/src/libbsc/Makefile.am | 1 | ||||
-rw-r--r-- | openbsc/src/libbsc/abis_rsl.c | 54 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_init.c | 21 | ||||
-rw-r--r-- | openbsc/src/libbsc/pcu_sock.c | 214 | ||||
-rw-r--r-- | openbsc/src/libcommon/debug.c | 5 |
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 { |