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 @@ enum hnb_audio_prim_type { /* 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 @@ struct hnb_audio_conn_establish_req_param { 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_conn_data_ind(uint32_t context_id, 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 @@ static int llsk_rx_sapi_version_cb(struct osmo_prim_srv *prim_srv, uint32_t sapi 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 @@ const struct value_string hnb_audio_prim_type_names[] = { { 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co 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 };