layer23: implement Rx/Tx API for GPRS related messages

Change-Id: I87950e893ef96ff8328f43f1548111aa9f66439b
Related: OS#5500
This commit is contained in:
Vadim Yanitskiy 2023-02-18 00:03:02 +07:00 committed by fixeria
parent 2b462dd89d
commit bb6df124d2
3 changed files with 117 additions and 0 deletions

View File

@ -75,4 +75,16 @@ int l1ctl_ph_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
/* Transmit L1CTL_NEIGH_PM_REQ */
int l1ctl_tx_neigh_pm_req(struct osmocom_ms *ms, int num, uint16_t *arfcn);
/* Transmit L1CTL_GPRS_UL_BLOCK_REQ */
int l1ctl_tx_gprs_ul_block_req(struct osmocom_ms *ms, uint32_t fn, uint8_t tn,
const uint8_t *data, size_t data_len);
/* Transmit L1CTL_GPRS_UL_TBF_CFG_REQ */
int l1ctl_tx_gprs_ul_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
uint8_t slotmask);
/* Transmit L1CTL_GPRS_DL_TBF_CFG_REQ */
int l1ctl_tx_gprs_dl_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
uint8_t slotmask, uint8_t dl_tfi);
#endif

View File

@ -36,6 +36,7 @@ struct osmosap_entity {
struct osmol1_entity {
int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg);
int (*l1_gprs_dl_block_ind)(struct osmocom_ms *ms, struct msgb *msg);
};
struct osmomncc_entity {

View File

@ -978,6 +978,107 @@ static int rx_l1_neigh_pm_ind(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
/* Receive L1CTL_GPRS_DL_BLOCK_IND */
static int rx_l1_gprs_dl_block_ind(struct osmocom_ms *ms, struct msgb *msg)
{
const struct l1ctl_gprs_dl_block_ind *ind = (void *)msg->l1h;
if (msgb_l1len(msg) < sizeof(*ind)) {
LOGP(DL1C, LOGL_ERROR,
"Rx malformed GPRS DL BLOCK.ind (len=%u < %zu)\n",
msgb_l1len(msg), sizeof(*ind));
return -EINVAL;
}
if (OSMO_UNLIKELY(ind->hdr.tn >= 8)) {
LOGP(DL1C, LOGL_ERROR,
"Rx malformed GPRS DL BLOCK.ind (tn=%u)\n",
ind->hdr.tn);
return -EINVAL;
}
msg->l2h = (void *)&ind->data[0];
DEBUGP(DL1C, "Rx GPRS DL block (fn=%u, tn=%u, len=%u): %s\n",
ntohl(ind->hdr.fn), ind->hdr.tn, msgb_l2len(msg), msgb_hexdump_l2(msg));
/* distribute or drop */
if (ms->l1_entity.l1_gprs_dl_block_ind)
return ms->l1_entity.l1_gprs_dl_block_ind(ms, msg);
msgb_free(msg);
return 0;
}
/* Transmit L1CTL_GPRS_UL_BLOCK_REQ */
int l1ctl_tx_gprs_ul_block_req(struct osmocom_ms *ms, uint32_t fn, uint8_t tn,
const uint8_t *data, size_t data_len)
{
struct l1ctl_gprs_ul_block_req *req;
struct msgb *msg;
msg = osmo_l1_alloc(L1CTL_GPRS_UL_BLOCK_REQ);
if (!msg)
return -ENOMEM;
req = (void *)msgb_put(msg, sizeof(*req));
req->hdr.fn = htonl(fn);
req->hdr.tn = tn;
if (data_len > 0)
memcpy(msgb_put(msg, data_len), data, data_len);
DEBUGP(DL1C, "Tx GPRS UL block (fn=%u, tn=%u, len=%zu): %s\n",
fn, tn, data_len, osmo_hexdump(data, data_len));
return osmo_send_l1(ms, msg);
}
/* Transmit L1CTL_GPRS_UL_TBF_CFG_REQ */
int l1ctl_tx_gprs_ul_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
uint8_t slotmask)
{
struct l1ctl_gprs_ul_tbf_cfg_req *req;
struct msgb *msg;
msg = osmo_l1_alloc(L1CTL_GPRS_UL_TBF_CFG_REQ);
if (!msg)
return -ENOMEM;
req = (void *)msgb_put(msg, sizeof(*req));
*req = (struct l1ctl_gprs_ul_tbf_cfg_req) {
.tbf_ref = tbf_ref,
.slotmask = slotmask,
};
DEBUGP(DL1C, "Tx GPRS UL TBF CFG (tbf_ref=%u, slotmask=0x%02x)\n",
tbf_ref, slotmask);
return osmo_send_l1(ms, msg);
}
/* Transmit L1CTL_GPRS_DL_TBF_CFG_REQ */
int l1ctl_tx_gprs_dl_tbf_cfg_req(struct osmocom_ms *ms, uint8_t tbf_ref,
uint8_t slotmask, uint8_t dl_tfi)
{
struct l1ctl_gprs_dl_tbf_cfg_req *req;
struct msgb *msg;
msg = osmo_l1_alloc(L1CTL_GPRS_DL_TBF_CFG_REQ);
if (!msg)
return -ENOMEM;
req = (void *)msgb_put(msg, sizeof(*req));
*req = (struct l1ctl_gprs_dl_tbf_cfg_req) {
.tbf_ref = tbf_ref,
.slotmask = slotmask,
.dl_tfi = dl_tfi,
};
DEBUGP(DL1C, "Tx GPRS DL TBF CFG (tbf_ref=%u, slotmask=0x%02x, dl_tfi=%u)\n",
tbf_ref, slotmask, dl_tfi);
return osmo_send_l1(ms, msg);
}
/* Receive incoming data from L1 using L1CTL format */
int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
{
@ -1046,6 +1147,9 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
case L1CTL_TRAFFIC_CONF:
msgb_free(msg);
break;
case L1CTL_GPRS_DL_BLOCK_IND:
rc = rx_l1_gprs_dl_block_ind(ms, msg);
break;
default:
LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", hdr->msg_type);
msgb_free(msg);