Support proto IPAC_PROTO_EXT_PCU BSC<->PCU

Related: SYS#5303
Change-Id: I633db291107883c2e370a9b56606d562a990b714
This commit is contained in:
Pau Espin 2021-06-23 19:46:07 +02:00
parent 8c29236d35
commit 1989a19066
4 changed files with 65 additions and 12 deletions

View File

@ -133,10 +133,12 @@ static void pcu_sock_close(int lost)
static int pcu_sock_read(struct osmo_fd *bfd)
{
struct gsm_pcu_if pcu_prim;
const size_t max_len = sizeof(struct gsm_pcu_if) + 1000;
uint8_t *buf = alloca(max_len);
struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *)buf;
int rc;
rc = recv(bfd->fd, &pcu_prim, sizeof(pcu_prim), 0);
rc = recv(bfd->fd, buf, max_len, 0);
if (rc < 0 && errno == EAGAIN)
return 0; /* Try again later */
if (rc <= 0) {
@ -144,7 +146,13 @@ static int pcu_sock_read(struct osmo_fd *bfd)
return -EIO;
}
return pcu_rx(pcu_prim.msg_type, &pcu_prim);
if (rc < PCUIF_HDR_SIZE) {
LOGP(DL1IF, LOGL_ERROR, "Received %d bytes on PCU Socket, but primitive "
"hdr size is %zu, discarding\n", rc, PCUIF_HDR_SIZE);
return -EINVAL;
}
return pcu_rx(pcu_prim, rc);
}
static int pcu_sock_write(struct osmo_fd *bfd)

View File

@ -951,9 +951,32 @@ static int pcu_rx_app_info_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_ap
return 0;
}
int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
static int pcu_rx_container(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_container *container)
{
int rc;
switch (container->msg_type) {
default:
LOGP(DL1IF, LOGL_NOTICE, "(bts=%d) Rx unexpected msg type (%u) inside container!\n",
bts->nr, container->msg_type);
rc = -1;
}
return rc;
}
#define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \
do { \
size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \
if (prim_len < _len) { \
LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive %s " \
"size is %zu, discarding\n", prim_len, #prim_msg, _len); \
return -EINVAL; \
} \
} while(0);
int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length)
{
int rc = 0;
size_t exp_len;
struct gprs_rlcmac_bts *bts = gprs_pcu_get_bts_by_nr(the_pcu, pcu_prim->bts_nr);
if (!bts) {
LOGP(DL1IF, LOGL_NOTICE, "Received message for new BTS%d\n", pcu_prim->bts_nr);
@ -964,40 +987,59 @@ int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim)
}
}
switch (msg_type) {
switch (pcu_prim->msg_type) {
case PCU_IF_MSG_DATA_IND:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_ind);
rc = pcu_rx_data_ind(bts, &pcu_prim->u.data_ind);
break;
case PCU_IF_MSG_DATA_CNF:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf);
rc = pcu_rx_data_cnf(bts, &pcu_prim->u.data_cnf);
break;
case PCU_IF_MSG_RTS_REQ:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rts_req);
rc = pcu_rx_rts_req(bts, &pcu_prim->u.rts_req);
break;
case PCU_IF_MSG_RACH_IND:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rach_ind);
rc = pcu_rx_rach_ind(bts, &pcu_prim->u.rach_ind);
break;
case PCU_IF_MSG_INFO_IND:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.info_ind);
rc = pcu_rx_info_ind(bts, &pcu_prim->u.info_ind);
break;
case PCU_IF_MSG_TIME_IND:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.time_ind);
rc = pcu_rx_time_ind(bts, &pcu_prim->u.time_ind);
break;
case PCU_IF_MSG_PAG_REQ:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.pag_req);
rc = pcu_rx_pag_req(bts, &pcu_prim->u.pag_req);
break;
case PCU_IF_MSG_SUSP_REQ:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.susp_req);
rc = pcu_rx_susp_req(bts, &pcu_prim->u.susp_req);
break;
case PCU_IF_MSG_APP_INFO_REQ:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.app_info_req);
rc = pcu_rx_app_info_req(bts, &pcu_prim->u.app_info_req);
break;
case PCU_IF_MSG_INTERF_IND:
/* TODO: handle interference reports */
break;
case PCU_IF_MSG_CONTAINER:
CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.container);
/* ^ check if we can access container fields, v check with container data length */
exp_len = PCUIF_HDR_SIZE + sizeof(pcu_prim->u.container) + osmo_load16be(&pcu_prim->u.container.length);
if (pcu_prim_length < exp_len) {
LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive container size" \
"is %zu, discarding\n", pcu_prim_length, exp_len);
}
rc = pcu_rx_container(bts, &pcu_prim->u.container);
break;
default:
LOGP(DL1IF, LOGL_ERROR, "Received unknown PCU msg type %d\n",
msg_type);
pcu_prim->msg_type);
rc = -EINVAL;
}

View File

@ -160,7 +160,7 @@ extern "C" {
#endif
struct gprs_rlcmac_bts;
int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim);
int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length);
int pcu_l1if_open(void);
void pcu_l1if_close(void);
int pcu_sock_send(struct msgb *msg);
@ -178,6 +178,9 @@ int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *
void pcu_rx_block_time(struct gprs_rlcmac_bts *bts, uint16_t arfcn, uint32_t fn, uint8_t ts_no);
uint16_t imsi2paging_group(const char* imsi);
#define PCUIF_HDR_SIZE ( sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u) )
#ifdef __cplusplus
}
#endif

View File

@ -72,7 +72,7 @@ void test_pcu_rx_no_subscr_with_active_tbf()
struct gsm_pcu_if pcu_prim = {PCU_IF_MSG_APP_INFO_REQ, };
fprintf(stderr, "--- %s ---\n", __func__);
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
fprintf(stderr, "\n");
}
@ -106,7 +106,7 @@ void test_sched_app_info_ok(const struct gsm_pcu_if_app_info_req *req)
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = *req;
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
msg = sched_app_info(tbf1);
assert(msg);
@ -126,7 +126,7 @@ void test_sched_app_info_missing_app_info_in_bts(const struct gsm_pcu_if_app_inf
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = *req;
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
msgb_free(bts->app_info);
bts->app_info = NULL;
@ -142,8 +142,8 @@ void test_pcu_rx_overwrite_app_info(const struct gsm_pcu_if_app_info_req *req)
fprintf(stderr, "--- %s ---\n", __func__);
pcu_prim.u.app_info_req = *req;
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(PCU_IF_MSG_APP_INFO_REQ, &pcu_prim);
pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
pcu_rx(&pcu_prim, sizeof(struct gsm_pcu_if));
fprintf(stderr, "\n");
}