laforge has submitted this change. (
https://gerrit.osmocom.org/c/osmo-hnodeb/+/28251 )
Change subject: audio: Introduce SAPI v1 with unordered RFCI support
......................................................................
audio: Introduce SAPI v1 with unordered RFCI support
This commit introduces support for the new llsk_audio SAPI v1.
This new version is almost the same as v0, with the exception that
primitive <REQUEST,HNB_AUDIO_PRIM_CONN_ESTABLISH> wins an extra field
appended at the end:
"""
uint8_t rfci[HNB_MAX_RFCIS]; /* values range 6 bits */
"""
This allows lowerlayers to provide an unordered array of RFCIs, which
was seen may happen under some conditions. For instance:
"""
rfci[HNB_MAX_RFCIS] = { 2, 3, 1};
[0] RFCI 2
[1] RFCI 3
[2] RFCI 1
"""
OsmoHNodeB still supports v0 if the lowerlayer asks for it, and will
continue having the exact behavior as before in this case (using
position in the array as RFCI). Hence, no compatibility breakage occurs
in this patch. New clients, on the other hand, can provide the extra
information by announcing V1 support during version negotiation at
startup.
Related: SYS#5516
Change-Id: I860d18b80c1041bf63a1570d435e0568c0f6b01b
---
M include/osmocom/hnodeb/hnb_prim.h
M include/osmocom/hnodeb/llsk.h
M src/osmo-hnodeb/llsk.c
M src/osmo-hnodeb/llsk_audio.c
M src/osmo-hnodeb/rtp.c
5 files changed, 64 insertions(+), 29 deletions(-)
Approvals:
Jenkins Builder: Verified
osmith: Looks good to me, but someone else must approve
laforge: Looks good to me, approved
diff --git a/include/osmocom/hnodeb/hnb_prim.h b/include/osmocom/hnodeb/hnb_prim.h
index ba3223d..be5cba2 100644
--- a/include/osmocom/hnodeb/hnb_prim.h
+++ b/include/osmocom/hnodeb/hnb_prim.h
@@ -188,7 +188,7 @@
/* HNB_AUDIO_PRIM_CONN_ESTABLISH, UL */
#define HNB_MAX_RFCIS 64
#define HNB_MAX_SUBFLOWS 7
-struct hnb_audio_conn_establish_req_param {
+struct hnb_audio_conn_establish_req_param_v0 {
uint32_t context_id;
uint16_t remote_rtp_port;
uint8_t spare1;
@@ -204,6 +204,16 @@
uint8_t IPTIs_present; /* 1=present; 0=not present */
uint8_t IPTIs[HNB_MAX_RFCIS]; /* values range 0-15, 4 bits */
} __attribute__ ((packed));
+struct hnb_audio_conn_establish_req_param_v1 {
+ struct hnb_audio_conn_establish_req_param_v0 v0;
+ uint8_t rfci[HNB_MAX_RFCIS]; /* values range 6 bits */
+} __attribute__ ((packed));
+struct hnb_audio_conn_establish_req_param {
+ union {
+ struct hnb_audio_conn_establish_req_param_v0 v0;
+ struct hnb_audio_conn_establish_req_param_v1 v1;
+ } __attribute__ ((packed));
+} __attribute__ ((packed));
/* HNB_AUDIO_PRIM_CONN_ESTABLISH, DL */
struct hnb_audio_conn_establish_cnf_param {
diff --git a/include/osmocom/hnodeb/llsk.h b/include/osmocom/hnodeb/llsk.h
index d9e1a69..bde531a 100644
--- a/include/osmocom/hnodeb/llsk.h
+++ b/include/osmocom/hnodeb/llsk.h
@@ -51,8 +51,9 @@
struct hnb_iuh_prim *hnb_iuh_makeprim_unitdata_ind(const uint8_t *data, uint32_t
data_len);
#define LLSK_SAPI_AUDIO_VERSION_MIN 0
-#define LLSK_SAPI_AUDIO_VERSION_MAX 0
+#define LLSK_SAPI_AUDIO_VERSION_MAX 1
extern const struct value_string hnb_audio_prim_type_names[];
+int llsk_audio_sapi_version_confirmed(uint16_t sapi_version);
int llsk_rx_audio(struct hnb *hnb, struct osmo_prim_hdr *oph);
int llsk_audio_tx_conn_data_ind(struct rtp_conn *conn, uint8_t frame_nr, uint8_t fqc,
uint8_t rfci,
const uint8_t *payload, uint32_t len);
diff --git a/src/osmo-hnodeb/llsk.c b/src/osmo-hnodeb/llsk.c
index b56cae7..f2d778f 100644
--- a/src/osmo-hnodeb/llsk.c
+++ b/src/osmo-hnodeb/llsk.c
@@ -167,6 +167,8 @@
return -1;
if (rem_version > LLSK_SAPI_AUDIO_VERSION_MAX)
return LLSK_SAPI_AUDIO_VERSION_MAX;
+ if (llsk_audio_sapi_version_confirmed(hnb->llsk.sapi_version_audio) < 0)
+ return -1;
hnb->llsk.sapi_version_audio = rem_version;
break;
default:
diff --git a/src/osmo-hnodeb/llsk_audio.c b/src/osmo-hnodeb/llsk_audio.c
index a9fe858..a545ee7 100644
--- a/src/osmo-hnodeb/llsk_audio.c
+++ b/src/osmo-hnodeb/llsk_audio.c
@@ -68,6 +68,24 @@
{ 0, NULL }
};
+int llsk_audio_sapi_version_confirmed(uint16_t sapi_version)
+{
+ /* Update primitive size expectancies based on SAPI version: */
+ switch (sapi_version) {
+ case 0:
+ llsk_audio_prim_size_tbl[PRIM_OP_REQUEST][HNB_AUDIO_PRIM_CONN_ESTABLISH] =
+ sizeof(struct hnb_audio_conn_establish_req_param_v0);
+ break;
+ case 1:
+ llsk_audio_prim_size_tbl[PRIM_OP_REQUEST][HNB_AUDIO_PRIM_CONN_ESTABLISH] =
+ sizeof(struct hnb_audio_conn_establish_req_param_v1);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
static struct hnb_audio_prim *hnb_audio_prim_alloc(enum hnb_audio_prim_type ptype, enum
osmo_prim_operation op, size_t extra_len)
{
struct osmo_prim_hdr *oph;
@@ -159,34 +177,35 @@
union u_addr loc_uaddr = {0};
uint16_t loc_port = 0;
struct rtp_conn *conn = NULL;
+ struct hnb_audio_conn_establish_req_param_v0 *v0 = &ce_req->v0;
- rc = ll_addr2osa(ce_req->remote_rtp_address_type, &ce_req->remote_rtp_addr,
ce_req->remote_rtp_port, &rem_osa);
+ rc = ll_addr2osa(v0->remote_rtp_address_type, &v0->remote_rtp_addr,
v0->remote_rtp_port, &rem_osa);
if (rc < 0) {
LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: ctx=%u with unexpected
address type %u\n",
- ce_req->context_id, ce_req->remote_rtp_address_type);
- return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 1);
+ v0->context_id, v0->remote_rtp_address_type);
+ return _send_conn_establish_cnf_failed(hnb, v0->context_id, 1);
}
osmo_sockaddr_to_str_buf(rem_addrstr, sizeof(rem_addrstr), &rem_osa);
LOGP(DLLSK, LOGL_INFO, "Rx AUDIO-CONN_ESTABLISH.req ctx=%u rem_addr=%s\n",
- ce_req->context_id, rem_addrstr);
+ v0->context_id, rem_addrstr);
- if ((af = ll_addr_type2af(ce_req->remote_rtp_address_type)) < 0) {
+ if ((af = ll_addr_type2af(v0->remote_rtp_address_type)) < 0) {
LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: ctx=%u with unexpected
address type %u\n",
- ce_req->context_id, ce_req->remote_rtp_address_type);
- return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 1);
+ v0->context_id, v0->remote_rtp_address_type);
+ return _send_conn_establish_cnf_failed(hnb, v0->context_id, 1);
}
- ue = hnb_find_ue_by_id(hnb, ce_req->context_id);
+ ue = hnb_find_ue_by_id(hnb, v0->context_id);
if (!ue) {
LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: UE not found! ctx=%u
rem_addr=%s\n",
- ce_req->context_id, rem_addrstr);
- return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 2);
+ v0->context_id, rem_addrstr);
+ return _send_conn_establish_cnf_failed(hnb, v0->context_id, 2);
}
if (!ue->conn_cs.active) {
LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: CS chan not active!
rem_addr=%s\n",
rem_addrstr);
- return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 3);
+ return _send_conn_establish_cnf_failed(hnb, v0->context_id, 3);
}
/* Create the socket: */
@@ -194,22 +213,22 @@
if ((rc = rtp_conn_setup(conn, &rem_osa, ce_req)) < 0) {
LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to set up audio
socket rem_addr=%s\n",
rem_addrstr);
- return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
+ return _send_conn_establish_cnf_failed(hnb, v0->context_id, 4);
}
/* Convert resulting local address back to LLSK format: */
- if (osa2_ll_addr(&conn->loc_addr, &loc_uaddr, &loc_port) !=
ce_req->remote_rtp_address_type) {
+ if (osa2_ll_addr(&conn->loc_addr, &loc_uaddr, &loc_port) !=
v0->remote_rtp_address_type) {
LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to provide
proper local address rem_addr=%s\n",
rem_addrstr);
- rc = _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
+ rc = _send_conn_establish_cnf_failed(hnb, v0->context_id, 4);
goto release_sock;
}
/* Submit successful confirmation */
LOGUE(ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_ESTABLISH.cnf: error_code=0 rem_addr=%s
loc_addr=%s\n",
rem_addrstr, osmo_sockaddr_to_str(&conn->loc_addr));
- audio_prim = hnb_audio_makeprim_conn_establish_cnf(ce_req->context_id, conn->id,
0, loc_port,
- ce_req->remote_rtp_address_type, &loc_uaddr);
+ audio_prim = hnb_audio_makeprim_conn_establish_cnf(v0->context_id, conn->id, 0,
loc_port,
+ v0->remote_rtp_address_type, &loc_uaddr);
if ((rc = osmo_prim_srv_send(hnb->llsk.srv, audio_prim->hdr.msg)) < 0) {
LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_ESTABLISH.cnf
error_code=0\n");
goto release_sock;
diff --git a/src/osmo-hnodeb/rtp.c b/src/osmo-hnodeb/rtp.c
index c0d96a9..422e043 100644
--- a/src/osmo-hnodeb/rtp.c
+++ b/src/osmo-hnodeb/rtp.c
@@ -31,30 +31,33 @@
#define HNB_IUUP_MSGB_SIZE 4096
-static struct osmo_iuup_rnl_prim *llsk_audio_ce_to_iuup_rnl_cfg(void *ctx, const struct
hnb_audio_conn_establish_req_param *ce_req)
+static struct osmo_iuup_rnl_prim *llsk_audio_ce_to_iuup_rnl_cfg(struct rtp_conn *conn,
const struct hnb_audio_conn_establish_req_param *ce_req)
{
struct osmo_iuup_rnl_prim *irp;
struct osmo_iuup_rnl_config *cfg;
unsigned int i;
+ const struct hnb_audio_conn_establish_req_param_v0 *v0 = &ce_req->v0;
+ const struct hnb *hnb = conn->ue->hnb;
- irp = osmo_iuup_rnl_prim_alloc(ctx, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST,
HNB_IUUP_MSGB_SIZE);
+ irp = osmo_iuup_rnl_prim_alloc(conn, OSMO_IUUP_RNL_CONFIG, PRIM_OP_REQUEST,
HNB_IUUP_MSGB_SIZE);
cfg = &irp->u.config;
- cfg->transparent = !!ce_req->transparent;
+ cfg->transparent = !!v0->transparent;
cfg->active = true;
- cfg->data_pdu_type = ce_req->data_pdu_type;
- cfg->supported_versions_mask = ce_req->supported_versions_mask;
- cfg->num_rfci = ce_req->num_rfci;
- cfg->num_subflows = ce_req->num_subflows;
- cfg->IPTIs_present = ce_req->IPTIs_present;
+ cfg->data_pdu_type = v0->data_pdu_type;
+ cfg->supported_versions_mask = v0->supported_versions_mask;
+ cfg->num_rfci = v0->num_rfci;
+ cfg->num_subflows = v0->num_subflows;
+ cfg->IPTIs_present = v0->IPTIs_present;
OSMO_ASSERT(cfg->num_rfci <= ARRAY_SIZE(cfg->rfci));
OSMO_ASSERT(cfg->num_subflows <= ARRAY_SIZE(cfg->rfci[0].subflow_sizes));
for (i = 0; i < cfg->num_rfci; i++) {
cfg->rfci[i].used = true;
- cfg->rfci[i].id = i; /* Assume RFC ID from position, llsk_audio doesn't provide
info */
+ /* llsk_audio v0 doesn't provide info, assume RFC ID from position: */
+ cfg->rfci[i].id = (hnb->llsk.sapi_version_audio > 0) ? ce_req->v1.rfci[i] :
i;
if (cfg->IPTIs_present)
- cfg->rfci[i].IPTI = ce_req->IPTIs[i];
+ cfg->rfci[i].IPTI = v0->IPTIs[i];
if (cfg->num_subflows > 0)
- memcpy(&cfg->rfci[i].subflow_sizes[0], &ce_req->subflow_sizes[i][0],
cfg->num_subflows*sizeof(uint16_t));
+ memcpy(&cfg->rfci[i].subflow_sizes[0], &v0->subflow_sizes[i][0],
cfg->num_subflows*sizeof(uint16_t));
}
cfg->t_init = (struct osmo_iuup_rnl_config_timer){ .t_ms = IUUP_TIMER_INIT_T_DEFAULT,
.n_max = IUUP_TIMER_INIT_N_DEFAULT };
--
To view, visit
https://gerrit.osmocom.org/c/osmo-hnodeb/+/28251
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-hnodeb
Gerrit-Branch: master
Gerrit-Change-Id: I860d18b80c1041bf63a1570d435e0568c0f6b01b
Gerrit-Change-Number: 28251
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier(a)sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: merged