Updates in FAPI so in the future to be able to have a TPMI on MAC at gNB based on SRS

This commit is contained in:
Roberto Louro Magueta
2022-06-08 11:37:03 +01:00
parent 0a496f44c4
commit fa94c338a8
9 changed files with 384 additions and 155 deletions
@@ -4060,4 +4060,23 @@ int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len);
*/
int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp);
/*! \brief Encodes a nfapi_nr_srs_beamforming_report_t to a buffer
*
* \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure
* \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_beamforming_report_t will be packed into
* \param packedBufLen The size of the buffer
* \return number of bytes written to the buffer
*/
int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
/*! \brief Decodes a nfapi_nr_srs_beamforming_report_t from a buffer
*
* \param pMessageBuf A pointer to an encoded nfapi_nr_srs_beamforming_report_t
* \param messageBufLen The size of the encoded nfapi_nr_srs_beamforming_report_t
* \param pUnpackedBuf A pointer to the nfapi_nr_srs_beamforming_report_t
* \param unpackedBufLen The size of nfapi_nr_srs_beamforming_report_t structure.
* \return 0 means success, -1 means failure.
*/
int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen);
#endif /* _NFAPI_INTERFACE_H_ */
@@ -1114,17 +1114,15 @@ typedef struct {
typedef struct
{
nfapi_nr_dig_bf_interface_t* dig_bf_interface_list;
} nfapi_nr_ul_beamforming_number_of_prgs_t;
typedef struct
{
uint16_t num_prgs;
uint16_t prg_size;
//watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces
uint8_t dig_bf_interface;
nfapi_nr_ul_beamforming_number_of_prgs_t* prgs_list;//
uint8_t trp_scheme; // This field shall be set to 0, to identify that this table is used.
uint16_t num_prgs; // Number of PRGs spanning this allocation. Value : 1->275
uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275
uint8_t dig_bf_interface; // Number of logical antenna ports (parallel streams) resulting from the Rx combining. Value: 0->255
nfapi_nr_ul_beamforming_number_of_prgs_t *prgs_list;
} nfapi_nr_ul_beamforming_t;
typedef struct
@@ -1298,6 +1296,28 @@ typedef struct
} nfapi_nr_pucch_pdu_t;
typedef struct {
uint16_t srs_bandwidth_start; // PRB index for the start of SRS signal transmission. The PRB index is relative to the CRB0 or reference Point A. 3GPP TS 38.211, section 6.4.1.4.3. Value: 0->268
uint8_t sequence_group; // Sequence group (u) as defined in 3GPP TS 38.211, section 6.4.1.4.2. Value: 0->29
uint8_t sequence_number; // Sequence number (v) as defined in 3GPP TS 38.211, section 6.4.1.4.2 TS 38.211. Value: 0->1
} nfapi_v4_srs_parameters_symbols_t;
typedef struct {
uint16_t srs_bandwidth_size; // mSRS,b: Number of PRB’s that are sounded for each SRS symbol, per 3GPP TS 38.211, section 6.4.1.4.3. Value: 4->272
nfapi_v4_srs_parameters_symbols_t *symbol_list;
uint32_t usage; // Bitmap indicating the type of report(s) expected at L2 from the SRS signaled by this PDU. Bit positions: 0 – beamManagement; 1 – codebook; 2 – nonCodebook; 3 – antennaSwitching; 4 – 255: reserved. For each of this bit positions: 1 = requested; 0 = not requested. nUsage = sum(all bits in usage)
uint8_t report_type[4]; // Interpretation of each Report Type depends on usage: beamManagement (1 = PRG SNR, 2-255 reserved); codebook (1 = PRG I and Q channel estimate, per srs Tx port and gNB antenna element, 2-255 reserved); nonCodebook (1 = PRG I and Q channel estimate, per SRI and gNB antenna element, 2-255 reserved); antennaSwitching (1 = SVD representation UE Rx and gNB sets of antenna element, 2-255 reserved); all (0 – no report required).
uint8_t singular_Value_representation; // 0 – 8-bit dB; 1 – 16-bit linear; 255 – not applicable
uint8_t iq_representation; // 0 – 16 bit; 1 – 32-bit; 255 - not applicable
uint16_t prg_size; // 1-272; 0 – reserved
uint8_t num_total_ue_antennas; // 1 … 16 in this release. This is the total number of UE antennas for the usage.
uint32_t ue_antennas_in_this_srs_resource_set; // Bitmap of UE antenna indices for the SRS Resource set, to which the SRS Resource for this PDU corresponds.
uint32_t sampled_ue_antennas; // Bitmap of UE antenna indices sampled by the SRS waveform corresponding to this PDU’s SRS Resource. Codebook: corresponds to antenna ports in SRS Resources; non-overlapping indices; Non-codebook: corresponds to SRIs; Antennas-switch: indices of UE Rx antennas in the total number of antennas.
uint8_t report_scope; // Which antennas Report (in ReportType) should account for: Value: 0: ports in sampledUeAntennas (i.e. SRS Resource); 1: ports in ueAntennasInSrsResourceSet (i.e. SRS Resource set. For antSwith reports of SVD type, value 0 is only allowed if sampledUeAntennas = ueAntennasInSrsResourceSet.
uint8_t num_ul_spatial_streams_ports; // In this release, L2 may set this number to 0 to leave spatial stream index assignment to L1 (e.g. L1 uses spatial streams reserved for SRS), regardless of the information in capability maxNumberUlSpatialStreams.
uint8_t Ul_spatial_stream_ports[256]; // Number of ports used for signaling this SRS allocation. Value: 0 --> (max # spatial streams - 1, per TLV)
} nfapi_v4_srs_parameters_t;
typedef struct {
uint16_t rnti; // UE RNTI, Value: 1->65535
uint32_t handle; // An opaque handling returned in the SRS.indication
@@ -1323,6 +1343,7 @@ typedef struct {
uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560
uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559
nfapi_nr_ul_beamforming_t beamforming;
nfapi_v4_srs_parameters_t srs_parameters_v4;
} nfapi_nr_srs_pdu_t;
typedef enum {
@@ -1666,33 +1687,63 @@ typedef struct
} nfapi_nr_uci_indication_t;
/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10, Table 3-73
/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10
// Normalized channel I/Q matrix
typedef struct {
uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid.
} nfapi_nr_srs_indication_reported_symbol_resource_block_t;
uint8_t normalized_iq_representation; // 0: 16-bit normalized complex number (iqSize = 2); 1: 32-bit normalized complex number (iqSize = 4)
uint16_t num_gnb_antenna_elements; // Ng: Number of gNB antenna elements. Value: 0511
uint16_t num_ue_srs_ports; // Nu: Number of sampled UE SRS ports. Value: 07
uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->272
uint16_t num_prgs; // Number of PRGs Np to be reported for this SRS PDU. Value: 0-> 272
uint8_t channel_matrix[272*512*8*4]; // Array of (numPRGs*Nu*Ng) entries of the type denoted by iqRepresentation H{PRG pI} [ueAntenna uI, gNB antenna gI] = array[uI*Ng*Np + gI*Np + pI]; uI: 0…Nu-1 (UE antenna index); gI: 0…Ng-1 (gNB antenna index); pI: 0…Np-1 (PRG index)
} nfapi_nr_srs_normalized_channel_iq_matrix_t;
// Beamforming report
typedef struct {
uint16_t num_rbs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272.
nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list;
} nfapi_nr_srs_indication_reported_symbol_t;
uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid.
} nfapi_nr_srs_reported_symbol_prgs_t;
typedef struct {
uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU.
uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535.
uint16_t timing_advance; // Timing advance TA measured for the UE [TS 38.213, Section 4.2]. NTA_new = NTA_old + (TA − 31) * 16 * 64 / (2^u). Value: 0 -> 63. 0xffff should be set if this field is invalid.
uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1.
uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid.
uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4.
nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list;
uint16_t num_prgs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272.
nfapi_nr_srs_reported_symbol_prgs_t *prg_list;
} nfapi_nr_srs_reported_symbol_t;
typedef struct {
uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275
uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1.
uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid.
uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4.
nfapi_nr_srs_reported_symbol_t *prgs;
} nfapi_nr_srs_beamforming_report_t;
// SRS indication
typedef struct {
uint16_t tag; // 0: Report is carried directly in the value field; 3: The offset from the end of the control portion of the message to the beginning of the report. Other values are reserved.
uint32_t length; // Length of the actual report in bytes, without the padding bytes.
uint32_t value[16384]; // tag=0: Only the most significant bytes of the size indicated by ‘length’ field are valid. Remaining bytes are zero padded to the nearest 32-bit bit boundary; Tag=2 Offset from the end of the control portion of the message to the payload is in the value field. Occupies 32-bits.
} nfapi_srs_report_tlv_t;
typedef struct {
uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU.
uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535.
uint16_t timing_advance_offset; // Timing advance TA measured for the UE in multiples of 16 * 64 * Tc / (2^u) [TS 38.213, Section 4.2]. Value: 0 -> 63. 0xffff will be set if this field is invalid.
int16_t timing_advance_offset_nsec; // Timing advance measured for the UE between the reference uplink time and the observed arrival time for the UE. Value: -16800 … +16800 nanoseconds. 0xffff should be set if this field is invalid.
uint8_t srs_usage; // 0 – beamManagement; 1 – codebook; 2 – nonCodebook; 3 – antennaSwitching; 4 – 255: reserved; Note: This field matches the SRS usage field of the SRS PDU to which this report is linked.
uint8_t report_type; // The type of report included in or pointed to by Report TLV depends on the SRS usage: Beam management (1: Beamforming report); Codebook (1: Normalized Channel I/Q Matrix); nonCodebook (1: Normalized Channel I/Q Matrix); antennaSwitch (1: Channel SVD Representation); all (0: null report)
nfapi_srs_report_tlv_t *report_tlv;
} nfapi_nr_srs_indication_pdu_t;
typedef struct {
nfapi_p7_message_header_t header;
uint16_t sfn; // SFN. Value: 0 -> 1023
uint16_t slot; // Slot. Value: 0 -> 159
uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255
nfapi_nr_srs_indication_pdu_t* pdu_list;
uint16_t sfn; // SFN. Value: 0 -> 1023
uint16_t slot; // Slot. Value: 0 -> 159
uint16_t control_length; // Size of control portion of SRS indication. 0 if reports are included inline; >0 if reports are concatenated to the end of the message.
uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255
nfapi_nr_srs_indication_pdu_t *pdu_list;
} nfapi_nr_srs_indication_t;
+179 -61
View File
@@ -3101,42 +3101,99 @@ return 1;
//SRS INDICATION
static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{
if(!(push32(value->handle, ppWritePackedMsg, end) &&
push16(value->rnti, ppWritePackedMsg, end) &&
push16(value->timing_advance, ppWritePackedMsg, end) &&
push8(value->num_symbols, ppWritePackedMsg, end) &&
push8(value->wide_band_snr, ppWritePackedMsg, end) &&
push8(value->num_reported_symbols, ppWritePackedMsg, end) &&
push8(value->reported_symbol_list->num_rbs, ppWritePackedMsg, end)
))
return 0;
for(int i = 0; i < value->reported_symbol_list->num_rbs; i++)
{
if (!push8(value->reported_symbol_list->rb_list[i].rb_snr, ppWritePackedMsg, end))
return 0;
}
return 1;
static uint8_t pack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppWritePackedMsg, uint8_t *end) {
if(!push16(prgs->num_prgs, ppWritePackedMsg, end)) {
return 0;
}
for(int i = 0; i < prgs->num_prgs; i++) {
if (!push8(prgs->prg_list[i].rb_snr, ppWritePackedMsg, end)) {
return 0;
}
}
return 1;
}
static uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t*)msg;
int pack_nr_srs_beamforming_report(void *pMessageBuf,
void *pPackedBuf,
uint32_t packedBufLen) {
if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)
))
return 0;
nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pMessageBuf;
for(int i=0; i<pNfapiMsg->number_of_pdus;i++)
{
if(!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]),ppWritePackedMsg,end))
return 0;
}
uint8_t *pWritePackedMessage = pPackedBuf;
uint8_t *end = pPackedBuf + packedBufLen;
return 1;
if(!(push16(nr_srs_beamforming_report->prg_size, &pWritePackedMessage, end) &&
push8(nr_srs_beamforming_report->num_symbols, &pWritePackedMessage, end) &&
push8(nr_srs_beamforming_report->wide_band_snr, &pWritePackedMessage, end) &&
push8(nr_srs_beamforming_report->num_reported_symbols, &pWritePackedMessage, end))) {
return 0;
}
if(!pack_nr_srs_reported_symbol(nr_srs_beamforming_report->prgs, &pWritePackedMessage, end)) {
return 0;
}
// Message length
uintptr_t msgHead = (uintptr_t)pPackedBuf;
uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
return (msgEnd-msgHead);
}
static uint8_t pack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
if(!(push16(report_tlv->tag, ppWritePackedMsg, end) &&
push32(report_tlv->length, ppWritePackedMsg, end))) {
return 0;
}
for(int i = 0; i < report_tlv->length; i++) {
if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) {
return 0;
}
}
return 1;
}
static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
if(!(push32(value->handle, ppWritePackedMsg, end) &&
push16(value->rnti, ppWritePackedMsg, end) &&
push16(value->timing_advance_offset, ppWritePackedMsg, end) &&
pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) &&
push8(value->srs_usage, ppWritePackedMsg, end) &&
push8(value->report_type, ppWritePackedMsg, end))) {
return 0;
}
if(!pack_nr_srs_report_tlv(value->report_tlv,ppWritePackedMsg, end)) {
return 0;
}
return 1;
}
static uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) {
nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t*)msg;
if (!(push16(pNfapiMsg->sfn , ppWritePackedMsg, end) &&
push16(pNfapiMsg->slot , ppWritePackedMsg, end) &&
push16(pNfapiMsg->control_length , ppWritePackedMsg, end) &&
push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) {
return 0;
}
for(int i=0; i<pNfapiMsg->number_of_pdus;i++) {
if(!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]),ppWritePackedMsg, end)) {
return 0;
}
}
return 1;
}
//RACH INDICATION
@@ -5797,40 +5854,101 @@ return 1;
//SRS INDICATION
static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t* value, uint8_t **ppReadPackedMsg, uint8_t *end)
{
if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
pull16(ppReadPackedMsg, &value->rnti, end) &&
pull16(ppReadPackedMsg, &value->timing_advance, end) &&
pull8(ppReadPackedMsg, &value->num_symbols, end) &&
pull8(ppReadPackedMsg, &value->wide_band_snr, end) &&
pull8(ppReadPackedMsg, &value->num_reported_symbols, end) &&
pull16(ppReadPackedMsg, &value->reported_symbol_list->num_rbs, end)
))
return 0;
for(int i = 0; i < value->reported_symbol_list->num_rbs; i++)
{
if (!pull8(ppReadPackedMsg, &value->reported_symbol_list->rb_list[i].rb_snr, end))
return 0;
}
return 1;
static uint8_t unpack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppReadPackedMsg, uint8_t *end) {
if(!pull16(ppReadPackedMsg, &prgs->num_prgs, end)) {
return 0;
}
if(!prgs->prg_list) {
prgs->prg_list = (nfapi_nr_srs_reported_symbol_prgs_t*) calloc(1, prgs->num_prgs*sizeof(nfapi_nr_srs_reported_symbol_prgs_t));
}
for(int i = 0; i < prgs->num_prgs; i++) {
if (!pull8(ppReadPackedMsg, &prgs->prg_list[i].rb_snr, end)) {
return 0;
}
}
return 1;
}
static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t* config)
{
if (!(pull16(ppReadPackedMsg,&pNfapiMsg->sfn , end) &&
pull16(ppReadPackedMsg,&pNfapiMsg->slot , end) &&
pull8(ppReadPackedMsg,&pNfapiMsg->number_of_pdus, end)
))
return 0;
int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen) {
for(int i=0; i<pNfapiMsg->number_of_pdus;i++)
{
if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end))
return 0;
}
nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pUnpackedBuf;
uint8_t *pReadPackedMessage = pMessageBuf;
uint8_t *end = pMessageBuf + messageBufLen;
return 1;
memset(pUnpackedBuf, 0, unpackedBufLen);
if(!(pull16(&pReadPackedMessage, &nr_srs_beamforming_report->prg_size, end) &&
pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_symbols, end) &&
pull8(&pReadPackedMessage, &nr_srs_beamforming_report->wide_band_snr, end) &&
pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_reported_symbols, end))) {
return -1;
}
if(!nr_srs_beamforming_report->prgs) {
nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, sizeof(nfapi_nr_srs_reported_symbol_t));
}
if(!unpack_nr_srs_reported_symbol(nr_srs_beamforming_report->prgs, &pReadPackedMessage, end)) {
return -1;
}
return 0;
}
static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) &&
pull32(ppReadPackedMsg, &report_tlv->length, end))) {
return 0;
}
for(int i = 0; i < report_tlv->length; i++) {
if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
return 0;
}
}
return 1;
}
static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) {
if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
pull16(ppReadPackedMsg, &value->rnti, end) &&
pull16(ppReadPackedMsg, &value->timing_advance_offset, end) &&
pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) &&
pull8(ppReadPackedMsg, &value->srs_usage, end) &&
pull8(ppReadPackedMsg, &value->report_type, end))) {
return 0;
}
if(!unpack_nr_srs_report_tlv(value->report_tlv, ppReadPackedMsg, end)) {
return 0;
}
return 1;
}
static uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_srs_indication_t *pNfapiMsg, nfapi_p7_codec_config_t* config) {
if (!(pull16(ppReadPackedMsg,&pNfapiMsg->sfn, end) &&
pull16(ppReadPackedMsg,&pNfapiMsg->slot, end) &&
pull16(ppReadPackedMsg,&pNfapiMsg->control_length, end) &&
pull8(ppReadPackedMsg,&pNfapiMsg->number_of_pdus, end))) {
return 0;
}
for(int i=0; i<pNfapiMsg->number_of_pdus; i++) {
if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) {
return 0;
}
}
return 1;
}
//NR RACH
+1
View File
@@ -98,6 +98,7 @@
#define NB_RX_ANTENNAS_MAX 64
#define TC_NSEC_x32768 16667
typedef enum {TDD=1,FDD=0} frame_type_t;
+60 -32
View File
@@ -633,27 +633,27 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
int fill_srs_reported_symbol_list(nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list,
int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs,
nfapi_nr_srs_pdu_t *srs_pdu,
int N_RB_UL,
const int8_t *snr_per_rb,
int srs_est) {
reported_symbol_list->num_rbs = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0];
prgs->num_prgs = srs_pdu->beamforming.num_prgs;
if (!reported_symbol_list->rb_list) {
reported_symbol_list->rb_list = (nfapi_nr_srs_indication_reported_symbol_resource_block_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_indication_reported_symbol_resource_block_t));
if (!prgs->prg_list) {
prgs->prg_list = (nfapi_nr_srs_reported_symbol_prgs_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_reported_symbol_prgs_t));
}
for(int rb = 0; rb < reported_symbol_list->num_rbs; rb++) {
for(int prg_idx = 0; prg_idx < prgs->num_prgs; prg_idx++) {
if (srs_est<0) {
reported_symbol_list->rb_list[rb].rb_snr = 0xFF;
} else if (snr_per_rb[rb] < -64) {
reported_symbol_list->rb_list[rb].rb_snr = 0;
} else if (snr_per_rb[rb] > 63) {
reported_symbol_list->rb_list[rb].rb_snr = 0xFE;
prgs->prg_list[prg_idx].rb_snr = 0xFF;
} else if (snr_per_rb[prg_idx] < -64) {
prgs->prg_list[prg_idx].rb_snr = 0;
} else if (snr_per_rb[prg_idx] > 63) {
prgs->prg_list[prg_idx].rb_snr = 0xFE;
} else {
reported_symbol_list->rb_list[rb].rb_snr = (snr_per_rb[rb] + 64)<<1;
prgs->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1;
}
}
@@ -890,36 +890,64 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
gNB->UL_INFO.srs_ind.slot = slot_rx;
gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle;
gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti;
gNB->srs_pdu_list[num_srs].timing_advance = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time[0]);
gNB->srs_pdu_list[num_srs].num_symbols = 1<<srs_pdu->num_symbols;
gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (*gNB->nr_srs_info[i]->snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid
gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<<srs_pdu->num_symbols;
if(!gNB->srs_pdu_list[num_srs].reported_symbol_list) {
gNB->srs_pdu_list[num_srs].reported_symbol_list = (nfapi_nr_srs_indication_reported_symbol_t*) calloc(1, gNB->srs_pdu_list[num_srs].num_reported_symbols*sizeof(nfapi_nr_srs_indication_reported_symbol_t));
}
fill_srs_reported_symbol_list(&gNB->srs_pdu_list[num_srs].reported_symbol_list[0],
gNB->srs_pdu_list[num_srs].timing_advance_offset = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time[0]);
gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec = (int16_t)(( ((int32_t)gNB->srs_pdu_list[num_srs].timing_advance_offset-31) * ((int32_t)TC_NSEC_x32768) ) >> 15);
gNB->srs_pdu_list[num_srs].srs_usage = srs_pdu->srs_parameters_v4.usage;
gNB->srs_pdu_list[num_srs].report_type = 1;
#ifdef SRS_IND_DEBUG
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn);
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = %04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance_offset_nsec = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].srs_usage = %i\n", num_srs, gNB->srs_pdu_list[num_srs].srs_usage);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_type = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_type);
#endif
nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t));
nr_srs_beamforming_report->prg_size = srs_pdu->beamforming.prg_size;
nr_srs_beamforming_report->num_symbols = 1<<srs_pdu->num_symbols;
nr_srs_beamforming_report->wide_band_snr = srs_est >= 0 ? (*gNB->nr_srs_info[i]->snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid
nr_srs_beamforming_report->num_reported_symbols = 1<<srs_pdu->num_symbols;
nr_srs_beamforming_report->prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report->num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t));
fill_srs_reported_symbol_list(&nr_srs_beamforming_report->prgs[0],
srs_pdu,
gNB->frame_parms.N_RB_UL,
gNB->nr_srs_info[i]->snr_per_rb,
srs_est);
gNB->UL_INFO.srs_ind.number_of_pdus += 1;
#ifdef SRS_IND_DEBUG
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn);
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = 0x%04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_symbols);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].wide_band_snr = %i\n", num_srs, gNB->srs_pdu_list[num_srs].wide_band_snr);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_reported_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_reported_symbols);
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].num_rbs = %i\n", num_srs, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs);
for(int rb = 0; rb < gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs; rb++) {
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].rb_list[%3i].rb_snr = %i\n",
num_srs, rb, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].rb_list[rb].rb_snr);
LOG_I(NR_PHY, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size);
LOG_I(NR_PHY, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols);
LOG_I(NR_PHY, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64);
LOG_I(NR_PHY, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols);
LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs);
for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) {
LOG_I(NR_PHY, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
prg_idx,
nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr,
(nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64);
}
#endif
if(!gNB->srs_pdu_list[num_srs].report_tlv) {
gNB->srs_pdu_list[num_srs].report_tlv = (nfapi_srs_report_tlv_t*) calloc(1, sizeof(nfapi_srs_report_tlv_t));
}
gNB->srs_pdu_list[num_srs].report_tlv->tag = 0;
gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_beamforming_report(nr_srs_beamforming_report,
gNB->srs_pdu_list[num_srs].report_tlv->value,
16384*sizeof(uint32_t));
#ifdef SRS_IND_DEBUG
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->length = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->length);
char *value = (char*)gNB->srs_pdu_list[num_srs].report_tlv->value;
for(int b = 0; b < gNB->srs_pdu_list[num_srs].report_tlv->length; b++) {
LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b]&0xFF);
}
#endif
gNB->UL_INFO.srs_ind.number_of_pdus += 1;
srs->active = 0;
}
}
+15 -4
View File
@@ -34,7 +34,12 @@
extern RAN_CONTEXT_t RC;
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) {
const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88,
96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160,
160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256,
256, 264, 272, 272, 272 };
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource) {
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
@@ -80,9 +85,15 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_U
srs_pdu->resource_type = srs_resource->resourceType.present - 1;
srs_pdu->t_srs = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
// TODO: This should be completed
srs_pdu->beamforming.trp_scheme = 0;
srs_pdu->beamforming.num_prgs = m_SRS[srs_pdu->config_index];
srs_pdu->beamforming.prg_size = 1;
srs_pdu->srs_parameters_v4.usage = srs_resource_set->usage;
}
void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_ResourceSet_t *srs_resource_set, NR_SRS_Resource_t *srs_resource) {
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
AssertFatal(future_ul_tti_req->n_pdus <
@@ -94,7 +105,7 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t s
memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t));
future_ul_tti_req->n_pdus += 1;
nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource);
nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource_set, srs_resource);
}
/*******************************************************************
@@ -185,7 +196,7 @@ void nr_schedule_srs(int module_id, frame_t frame) {
// Check if UE will transmit the SRS in this frame
if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) {
LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame);
nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource);
nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource_set, srs_resource);
sched_ctrl->sched_srs.frame = frame;
sched_ctrl->sched_srs.slot = offset%n_slots_frame;
sched_ctrl->sched_srs.srs_scheduled = true;
@@ -765,46 +765,57 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
void handle_nr_srs_measurements(const module_id_t module_id,
const frame_t frame,
const sub_frame_t slot,
const rnti_t rnti,
const uint16_t timing_advance,
const uint8_t num_symbols,
const uint8_t wide_band_snr,
const uint8_t num_reported_symbols,
nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list) {
const nfapi_nr_srs_indication_pdu_t *srs_ind) {
LOG_D(NR_MAC, "(%d.%d) Received SRS indication for rnti: 0x%04x\n", frame, slot, rnti);
LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti);
#ifdef SRS_IND_DEBUG
LOG_I(NR_MAC, "frame = %i\n", frame);
LOG_I(NR_MAC, "slot = %i\n", slot);
LOG_I(NR_MAC, "rnti = 0x%04x\n", rnti);
LOG_I(NR_MAC, "timing_advance = %i\n", timing_advance);
LOG_I(NR_MAC, "num_symbols = %i\n", num_symbols);
LOG_I(NR_MAC, "wide_band_snr = %i (%i dB)\n", wide_band_snr, (wide_band_snr>>1)-64);
LOG_I(NR_MAC, "num_reported_symbols = %i\n", num_reported_symbols);
LOG_I(NR_MAC, "reported_symbol_list[0].num_rbs = %i\n", reported_symbol_list[0].num_rbs);
for(int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) {
LOG_I(NR_MAC, "reported_symbol_list[0].rb_list[%3i].rb_snr = %i (%i dB)\n",
rb, reported_symbol_list[0].rb_list[rb].rb_snr, (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64);
LOG_I(NR_MAC, "srs_ind->rnti = %04x\n", srs_ind->rnti);
LOG_I(NR_MAC, "srs_ind->timing_advance_offset = %i\n", srs_ind->timing_advance_offset);
LOG_I(NR_MAC, "srs_ind->timing_advance_offset_nsec = %i\n", srs_ind->timing_advance_offset_nsec);
LOG_I(NR_MAC, "srs_ind->srs_usage = %i\n", srs_ind->srs_usage);
LOG_I(NR_MAC, "srs_ind->report_type = %i\n", srs_ind->report_type);
#endif
nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*) calloc(1,sizeof(nfapi_nr_srs_beamforming_report_t));
unpack_nr_srs_beamforming_report(srs_ind->report_tlv->value,
srs_ind->report_tlv->length,
nr_srs_beamforming_report,
sizeof(nfapi_nr_srs_beamforming_report_t));
#ifdef SRS_IND_DEBUG
LOG_I(NR_MAC, "nr_srs_beamforming_report->prg_size = %i\n", nr_srs_beamforming_report->prg_size);
LOG_I(NR_MAC, "nr_srs_beamforming_report->num_symbols = %i\n", nr_srs_beamforming_report->num_symbols);
LOG_I(NR_MAC, "nr_srs_beamforming_report->wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report->wide_band_snr, (nr_srs_beamforming_report->wide_band_snr>>1)-64);
LOG_I(NR_MAC, "nr_srs_beamforming_report->num_reported_symbols = %i\n", nr_srs_beamforming_report->num_reported_symbols);
LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].num_prgs = %i\n", nr_srs_beamforming_report->prgs[0].num_prgs);
for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report->prgs[0].num_prgs; prg_idx++) {
LOG_I(NR_MAC, "nr_srs_beamforming_report->prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
prg_idx,
nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr,
(nr_srs_beamforming_report->prgs[0].prg_list[prg_idx].rb_snr>>1)-64);
}
#endif
NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, rnti);
NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti);
if (!UE) {
LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti);
LOG_W(NR_MAC, "Could not find UE %04x\n", srs_ind->rnti);
return;
}
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_mac_stats_t *stats = &UE->mac_stats;
stats->srs_wide_band_snr = (wide_band_snr>>1)-64;
stats->srs_wide_band_snr = (nr_srs_beamforming_report->wide_band_snr>>1)-64;
int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold;
uint16_t *ulprbbl = nr_mac->ulprbbl;
memset(ulprbbl, 0, reported_symbol_list[0].num_rbs*sizeof(uint16_t));
for (int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) {
int snr = (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64;
uint8_t num_rbs = nr_srs_beamforming_report->prg_size * nr_srs_beamforming_report->prgs[0].num_prgs;
memset(ulprbbl, 0, num_rbs*sizeof(uint16_t));
for (int rb = 0; rb < num_rbs; rb++) {
int snr = (nr_srs_beamforming_report->prgs[0].prg_list[rb/nr_srs_beamforming_report->prg_size].rb_snr>>1)-64;
if (snr < ul_prbblack_SNR_threshold) {
ulprbbl[rb] = 0x3FFF; // all symbols taken
}
+1 -6
View File
@@ -493,12 +493,7 @@ void handle_nr_ul_harq(const int CC_idP,
void handle_nr_srs_measurements(const module_id_t module_id,
const frame_t frame,
const sub_frame_t slot,
const rnti_t rnti,
const uint16_t timing_advance,
const uint8_t num_symbols,
const uint8_t wide_band_snr,
const uint8_t num_reported_symbols,
nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list);
const nfapi_nr_srs_indication_pdu_t *srs_ind);
int16_t ssb_index_from_prach(module_id_t module_idP,
frame_t frameP,
+1 -6
View File
@@ -239,12 +239,7 @@ void handle_nr_srs(NR_UL_IND_t *UL_info) {
handle_nr_srs_measurements(module_id,
frame,
slot,
srs_ind->rnti,
srs_ind->timing_advance,
srs_ind->num_symbols,
srs_ind->wide_band_snr,
srs_ind->num_reported_symbols,
srs_ind->reported_symbol_list);
&srs_list[i]);
}
UL_info->srs_ind.number_of_pdus = 0;