nr_ue_procedures.c 24.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
/* \file ue_procedures.c
23
 * \brief procedures related to UE
24 25 26 27 28 29 30
 * \author R. Knopp, K.H. HSU
 * \date 2018
 * \version 0.1
 * \company Eurecom / NTUST
 * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr
 * \note
 * \warning
31
 */
32

33
#include "mac_proto.h"
34
#include "mac_extern.h"
35
#include "RRC/NR_UE/rrc_proto.h"
36
#include "assertions.h"
37

38
#include <stdio.h>
39
#include <math.h>
40

41 42 43 44 45 46 47
uint32_t get_ssb_slot(uint32_t ssb_index){
    //  this function now only support f <= 3GHz
    return ssb_index & 0x3 ;

    //  return first_symbol(case, freq, ssb_index) / 14
}

48
int8_t nr_ue_decode_mib(
49
	module_id_t module_id,
50
	int 		cc_id,
51
	uint8_t 	gNB_index,
52
	uint8_t 	extra_bits,	//	8bits 38.212 c7.1.1
53 54
	uint32_t    ssb_length,
	uint32_t 	ssb_index,
55 56
	void 		*pduP,
    uint16_t    cell_id ){
57

58 59
    printf("[L2][MAC] decode mib\n");

60 61
	NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);

62
    nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 );    //  fixed 3 bytes MIB PDU
63
    
64 65
    AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
    //if(mac->mib != NULL){
66 67 68 69 70 71
	    uint32_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused);
	    uint32_t frame_number_4lsb = (uint32_t)(extra_bits & 0xf);                      //	extra bits[0:3]
	    uint32_t half_frame_bit = (uint32_t)(( extra_bits >> 4 ) & 0x1 );               //	extra bits[4]
	    uint32_t ssb_subcarrier_offset_msb = (uint32_t)(( extra_bits >> 5 ) & 0x1 );    //	extra bits[5]
	    
	    uint32_t ssb_subcarrier_offset = mac->mib->ssb_SubcarrierOffset;
72

73
	    //uint32_t ssb_index = 0;    //  TODO: ssb_index should obtain from L1 in case Lssb != 64
74

75 76
	    frame = frame << 4;
	    frame = frame | frame_number_4lsb;
77

78 79
	    if(ssb_length == 64){
	    	ssb_index = ssb_index & (( extra_bits >> 2 ) & 0x1C );    //	{ extra_bits[5:7], ssb_index[2:0] }
80
	    }else{
81 82 83
			if(ssb_subcarrier_offset_msb){
			    ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
			}
84
	    }
85

86
#if 0
87 88 89 90 91 92 93 94 95 96
		printf("system frame number(6 MSB bits): %d\n",  mac->mib->systemFrameNumber.buf[0]);
		printf("system frame number(with LSB): %d\n", (int)frame);
		printf("subcarrier spacing:            %d\n", (int)mac->mib->subCarrierSpacingCommon);
		printf("ssb carrier offset(with MSB):  %d\n", (int)ssb_subcarrier_offset);
		printf("dmrs type A position:          %d\n", (int)mac->mib->dmrs_TypeA_Position);
		printf("pdcch config sib1:             %d\n", (int)mac->mib->pdcch_ConfigSIB1);
		printf("cell barred:                   %d\n", (int)mac->mib->cellBarred);
		printf("intra frequcney reselection:   %d\n", (int)mac->mib->intraFreqReselection);
		printf("half frame bit(extra bits):    %d\n", (int)half_frame_bit);
		printf("ssb index(extra bits):         %d\n", (int)ssb_index);
97 98
#endif

99 100 101 102 103 104 105 106 107 108 109 110
	    subcarrier_spacing_t scs_ssb = scs_30kHz;      //  default for testing
	    subcarrier_spacing_t scs_pdcch;

        //  assume carrier frequency < 6GHz
        if(mac->mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
            scs_pdcch = scs_15kHz;
        }else{  //NR_MIB__subCarrierSpacingCommon_scs30or120
            scs_pdcch = scs_30kHz;
        }


	    channel_bandwidth_t min_channel_bw = bw_40MHz;  //  deafult for testing
111
	    
112
        uint32_t is_condition_A = (ssb_subcarrier_offset == 0);   //  38.213 ch.13
113 114 115
        frequency_range_t frequency_range = FR1;
        uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1 >> 4) & 0xf;
        uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1 & 0xf);
116 117 118 119
        int32_t num_rbs = -1;
        int32_t num_symbols = -1;
        int32_t rb_offset = -1;

120 121 122 123
        //  type0-pdcch coreset
	    switch( (scs_ssb << 5)|scs_pdcch ){
            case (scs_15kHz << 5) | scs_15kHz :
                AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
124 125 126 127
                mac->type0_pdcch_ss_mux_pattern = 1;
                num_rbs     = table_38213_13_1_c2[index_4msb];
                num_symbols = table_38213_13_1_c3[index_4msb];
                rb_offset   = table_38213_13_1_c4[index_4msb];
128 129 130 131
                break;

	        case (scs_15kHz << 5) | scs_30kHz:
                AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
132 133 134 135
                mac->type0_pdcch_ss_mux_pattern = 1;
                num_rbs     = table_38213_13_2_c2[index_4msb];
                num_symbols = table_38213_13_2_c3[index_4msb];
                rb_offset   = table_38213_13_2_c4[index_4msb];
136 137 138 139 140
                break;

            case (scs_30kHz << 5) | scs_15kHz:
                if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
                    AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
141 142 143 144
                    mac->type0_pdcch_ss_mux_pattern = 1;
                    num_rbs     = table_38213_13_3_c2[index_4msb];
                    num_symbols = table_38213_13_3_c3[index_4msb];
                    rb_offset   = table_38213_13_3_c4[index_4msb];
145 146
                }else if(min_channel_bw & bw_40MHz){
                    AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n");
147 148 149 150
                    mac->type0_pdcch_ss_mux_pattern = 1;
                    num_rbs     = table_38213_13_5_c2[index_4msb];
                    num_symbols = table_38213_13_5_c3[index_4msb];
                    rb_offset   = table_38213_13_5_c4[index_4msb];
151 152 153 154 155 156
                }else{ ; }

                break;

            case (scs_30kHz << 5) | scs_30kHz:
                if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
157 158 159 160
                    mac->type0_pdcch_ss_mux_pattern = 1;
                    num_rbs     = table_38213_13_4_c2[index_4msb];
                    num_symbols = table_38213_13_4_c3[index_4msb];
                    rb_offset   = table_38213_13_4_c4[index_4msb];
161 162
                }else if(min_channel_bw & bw_40MHz){
                    AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n");
163 164 165 166
                    mac->type0_pdcch_ss_mux_pattern = 1;
                    num_rbs     = table_38213_13_6_c2[index_4msb];
                    num_symbols = table_38213_13_6_c3[index_4msb];
                    rb_offset   = table_38213_13_6_c4[index_4msb];
167 168 169 170 171 172
                }else{ ; }
                break;

            case (scs_120kHz << 5) | scs_60kHz:
                AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
                if(index_4msb & 0x7){
173
                    mac->type0_pdcch_ss_mux_pattern = 1;
174
                }else if(index_4msb & 0x18){
175
                    mac->type0_pdcch_ss_mux_pattern = 2;
176 177
                }else{ ; }

178 179
                num_rbs     = table_38213_13_7_c2[index_4msb];
                num_symbols = table_38213_13_7_c3[index_4msb];
180
                if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){
181
                    rb_offset   = table_38213_13_7_c4[index_4msb] - 1;
182
                }else{
183
                    rb_offset   = table_38213_13_7_c4[index_4msb];
184 185 186 187 188 189
                }
                break;

            case (scs_120kHz << 5) | scs_120kHz:
                AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
                if(index_4msb & 0x3){
190
                    mac->type0_pdcch_ss_mux_pattern = 1;
191
                }else if(index_4msb & 0x0c){
192
                    mac->type0_pdcch_ss_mux_pattern = 3;
193 194
                }

195 196
                num_rbs     = table_38213_13_8_c2[index_4msb];
                num_symbols = table_38213_13_8_c3[index_4msb];
197
                if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
198
                    rb_offset   = table_38213_13_8_c4[index_4msb] - 1;
199
                }else{
200
                    rb_offset   = table_38213_13_8_c4[index_4msb];
201 202 203 204 205
                }
                break;

            case (scs_240kHz << 5) | scs_60kHz:
                AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
206 207 208 209
                mac->type0_pdcch_ss_mux_pattern = 1;
                num_rbs     = table_38213_13_9_c2[index_4msb];
                num_symbols = table_38213_13_9_c3[index_4msb];
                rb_offset   = table_38213_13_9_c4[index_4msb];
210 211 212 213 214
                break;

            case (scs_240kHz << 5) | scs_120kHz:
                AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
                if(index_4msb & 0x3){
215
                    mac->type0_pdcch_ss_mux_pattern = 1;
216
                }else if(index_4msb & 0x0c){
217
                    mac->type0_pdcch_ss_mux_pattern = 2;
218
                }
219 220
                num_rbs     = table_38213_13_10_c2[index_4msb];
                num_symbols = table_38213_13_10_c3[index_4msb];
221
                if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
222
                    rb_offset   = table_38213_13_10_c4[index_4msb]-1;
223
                }else{
224
                    rb_offset   = table_38213_13_10_c4[index_4msb];
225 226 227 228 229 230 231 232
                }
                
                break;

	        default:
	            break;
	    }

233 234 235 236
        AssertFatal(num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined");
        AssertFatal(num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined");
        AssertFatal(rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined");
        
237
        //uint32_t cell_id = 0;   //  obtain from L1 later
238

239 240 241 242
        mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset;
        mac->type0_pdcch_dci_config.coreset.rb_end = rb_offset + num_rbs - 1;
        //mac->type0_pdcch_dci_config.type0_pdcch_coreset.duration = num_symbols;
        mac->type0_pdcch_dci_config.coreset.cce_reg_mapping_type = CCE_REG_MAPPING_TYPE_INTERLEAVED;
243 244
        mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_reg_bundle_size = 6;   //  L 38.211 7.3.2.2
        mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_interleaver_size = 2;  //  R 38.211 7.3.2.2
245 246 247
        mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_shift_index = cell_id;
        mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE;
        mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id;
248 249 250



251 252 253
        // type0-pdcch search space
        float big_o;
        float big_m;
254
        uint32_t temp;
255
        SFN_C_TYPE sfn_c;   //  only valid for mux=1
256 257
        uint32_t n_c;
        uint32_t number_of_search_space_per_slot;
258
        uint32_t first_symbol_index;
259 260
        uint32_t search_space_duration;  //  element of search space
        uint32_t coreset_duration;  //  element of coreset
261

262
const uint32_t scs_index = 0;
263
const uint32_t num_slot_per_frame = 20;
264 265 266 267
        
        //  38.213 table 10.1-1
        

268

269 270
        /// MUX PATTERN 1
        if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
271 272 273 274
            big_o = table_38213_13_11_c1[index_4lsb];
            number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
            big_m = table_38213_13_11_c3[index_4lsb];

275 276 277 278 279 280 281 282
            temp = (uint32_t)(big_o*pow(2, scs_index)) + (uint32_t)(ssb_index*big_m);
            n_c = temp / num_slot_per_frame;
            if((temp/num_slot_per_frame) & 0x1){
                sfn_c = SFN_C_MOD_2_EQ_1;
            }else{
                sfn_c = SFN_C_MOD_2_EQ_0;
            }

283 284
            if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ssb_index&1)){
                first_symbol_index = num_symbols;
285 286 287
            }else{
                first_symbol_index = table_38213_13_11_c4[index_4lsb];
            }
288 289
            //  38.213 chapter 13: over two consecutive slots
            search_space_duration = 2;
290 291
        }

292
        if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
293 294 295 296
            big_o = table_38213_13_12_c1[index_4lsb];
            number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
            big_m = table_38213_13_12_c3[index_4lsb];

297
            if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ssb_index&1)){
298
                first_symbol_index = 7;
299 300
            }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ssb_index&1)){
                first_symbol_index = num_symbols;
301 302 303
            }else{
                first_symbol_index = 0;
            }
304 305
            //  38.213 chapter 13: over two consecutive slots
            search_space_duration = 2;
306 307
        }

308 309 310
        
        /// MUX PATTERN 2
        if(mac->type0_pdcch_ss_mux_pattern == 2){
311
            
312 313 314
            if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
                //  38.213 Table 13-13
                AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
315
                //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
316
//                sfn_c = SFN_C_EQ_SFN_SSB;
317
                n_c = get_ssb_slot(ssb_index);
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
                switch(ssb_index & 0x3){    //  ssb_index(i) mod 4
                    case 0: 
                        first_symbol_index = 0;
                        break;
                    case 1: 
                        first_symbol_index = 1;
                        break;
                    case 2: 
                        first_symbol_index = 6;
                        break;
                    case 3: 
                        first_symbol_index = 7;
                        break;
                    default: break; 
                }
                
334 335 336
            }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
                //  38.213 Table 13-14
                AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
337
                //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
338
//                sfn_c = SFN_C_EQ_SFN_SSB;
339
                n_c = get_ssb_slot(ssb_index);
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
                switch(ssb_index & 0x7){    //  ssb_index(i) mod 8
                    case 0: 
                        first_symbol_index = 0;
                        break;
                    case 1: 
                        first_symbol_index = 1;
                        break;
                    case 2: 
                        first_symbol_index = 2;
                        break;
                    case 3: 
                        first_symbol_index = 3;
                        break;
                    case 4: 
                        first_symbol_index = 12;
355
                        n_c = get_ssb_slot(ssb_index) - 1;
356 357 358
                        break;
                    case 5: 
                        first_symbol_index = 13;
359
                        n_c = get_ssb_slot(ssb_index) - 1;
360 361 362 363 364 365 366 367 368
                        break;
                    case 6: 
                        first_symbol_index = 0;
                        break;
                    case 7: 
                        first_symbol_index = 1;
                        break;
                    default: break; 
                }
369
            }else{ ; }
370 371
            //  38.213 chapter 13: over one slot
            search_space_duration = 1;
372 373
        }

374 375
        /// MUX PATTERN 3
        if(mac->type0_pdcch_ss_mux_pattern == 3){
376 377 378
            if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
                //  38.213 Table 13-15
                AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
379
                //  PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
380
//                sfn_c = SFN_C_EQ_SFN_SSB;
381
                n_c = get_ssb_slot(ssb_index);
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
                switch(ssb_index & 0x3){    //  ssb_index(i) mod 4
                    case 0: 
                        first_symbol_index = 4;
                        break;
                    case 1: 
                        first_symbol_index = 8;
                        break;
                    case 2: 
                        first_symbol_index = 2;
                        break;
                    case 3: 
                        first_symbol_index = 6;
                        break;
                    default: break; 
                }
397
            }else{ ; }
398 399
            //  38.213 chapter 13: over one slot
            search_space_duration = 1;
400
        }
401

402 403
        coreset_duration = num_symbols * number_of_search_space_per_slot;

404 405 406 407 408
        mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0];
        mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1];
        mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2];   //  CCE aggregation level = 4
        mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3];   //  CCE aggregation level = 8
        mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4];   //  CCE aggregation level = 16
409 410 411 412
        mac->type0_pdcch_dci_config.duration = search_space_duration;
        mac->type0_pdcch_dci_config.coreset.duration = coreset_duration;   //  coreset
        mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff;

413 414
        mac->type0_pdcch_ss_sfn_c = sfn_c;
        mac->type0_pdcch_ss_n_c = n_c;
415
        
416

417 418 419 420 421 422 423 424 425 426 427
	    // fill in the elements in config request inside P5 message
	    mac->phy_config.config_req.pbch_config.system_frame_number = frame;    //  after calculation
	    mac->phy_config.config_req.pbch_config.subcarrier_spacing_common = mac->mib->subCarrierSpacingCommon;
	    mac->phy_config.config_req.pbch_config.ssb_subcarrier_offset = ssb_subcarrier_offset;  //  after calculation
	    mac->phy_config.config_req.pbch_config.dmrs_type_a_position = mac->mib->dmrs_TypeA_Position;
	    mac->phy_config.config_req.pbch_config.pdcch_config_sib1 = mac->mib->pdcch_ConfigSIB1;
	    mac->phy_config.config_req.pbch_config.cell_barred = mac->mib->cellBarred;
	    mac->phy_config.config_req.pbch_config.intra_frequency_reselection = mac->mib->intraFreqReselection;
	    mac->phy_config.config_req.pbch_config.half_frame_bit = half_frame_bit;
	    mac->phy_config.config_req.pbch_config.ssb_index = ssb_index;
	    mac->phy_config.config_req.config_mask |= FAPI_NR_CONFIG_REQUEST_MASK_PBCH;
428

429 430 431
	    if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL){
		mac->if_module->phy_config_request(&mac->phy_config);
	    }
432
    //}
433
    return 0;
434
}
ChenWeiTai's avatar
ChenWeiTai committed
435

436

437 438

//  TODO: change to UE parameter, scs: 15KHz, slot duration: 1ms
439 440 441 442
uint32_t get_ssb_frame(){
	return 0;
}

443 444 445 446 447 448 449 450 451 452
// Performs :
// 1. TODO: Call RRC for link status return to PHY
// 2. TODO: Perform SR/BSR procedures for scheduling feedback
// 3. TODO: Perform PHR procedures
NR_UE_L2_STATE_t nr_ue_scheduler(
    const module_id_t module_id,
    const uint8_t gNB_index,
    const int cc_id,
    const frame_t rx_frame,
    const slot_t rx_slot,
453
    const int32_t ssb_index,
454
    const frame_t tx_frame,
455 456 457 458
    const slot_t tx_slot ){

    uint32_t search_space_mask = 0;
    NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
459
    
460 461 462 463
    //  check type0 from 38.213 13
    if(ssb_index != -1){

        if(mac->type0_pdcch_ss_mux_pattern == 1){
464 465 466
            //	38.213 chapter 13
            if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
            	search_space_mask = search_space_mask | type0_pdcch;
467
                mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration;
468 469 470
            }
            if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) &&  (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
            	search_space_mask = search_space_mask | type0_pdcch;
471
                mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration;
472
            }
473 474 475
            //if((mac->type0_pdcch_ss_sfn_c == SFN_C_EQ_SFN_SSB) && ( get_ssb_frame() )){
            //	search_space_mask = search_space_mask | type0_pdcch;
            //}
476 477
        }
        if(mac->type0_pdcch_ss_mux_pattern == 2){
478 479 480
            //	38.213 Table 13-13, 13-14
            if((rx_frame == get_ssb_frame()) && (rx_slot == mac->type0_pdcch_ss_n_c)){
                search_space_mask = search_space_mask | type0_pdcch;
481
                mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration;
482 483 484
            }
        }
        if(mac->type0_pdcch_ss_mux_pattern == 3){
485 486 487
        	//	38.213 Table 13-15
            if((rx_frame == get_ssb_frame()) && (rx_slot == mac->type0_pdcch_ss_n_c)){
                search_space_mask = search_space_mask | type0_pdcch;
488
                mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration;
489 490 491
            }
        }
    }
492

493 494 495 496 497 498 499 500 501 502 503 504 505
#if 0
		uint16_t rnti;

        fapi_nr_coreset_t coreset;
        uint32_t duration;
        uint8_t aggregation_level;
        uint8_t number_of_candidates;
        uint16_t monitoring_symbols_within_slot;
        //  DCI foramt-specific
        uint8_t format_2_0_number_of_candidates[5];    //  aggregation level 1, 2, 4, 8, 16
        uint8_t format_2_3_monitorying_periodicity;
        uint8_t format_2_3_number_of_candidates;
#endif
506
    fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
507 508
    if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){
        mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1;
509

510 511
        dl_config->dl_config_list[dl_config->number_pdus].dci_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config;
        dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
512 513
        dl_config->number_pdus = dl_config->number_pdus + 1;
    	
514
    	dl_config->dl_config_list[dl_config->number_pdus].dci_pdu.dci_config_rel15.rnti = 0xaaaa;	//	to be set
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
    }

    if(search_space_mask & type0a_pdcch){
    }

    if(search_space_mask & type1_pdcch){
    }

    if(search_space_mask & type2_pdcch){
    }

    if(search_space_mask & type3_pdcch){
    }


    mac->scheduled_response.dl_config = dl_config;
    
532 533

	return CONNECTION_OK;
534 535
}

536
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_type){
537 538 539 540 541 542 543

    NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);

    if(rnti == SI_RNTI){

    }else if(rnti == mac->ra_rnti){

544 545 546 547 548 549 550 551 552 553
    }else if(rnti == P_RNTI){

    }else{  //  c-rnti

        ///  check if this is pdcch order 
        //dci->random_access_preamble_index;
        //dci->ss_pbch_index;
        //dci->prach_mask_index;

        ///  else normal DL-SCH grant
554 555
    }
}
556

557
int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe){
558 559

    return 0;
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
}



void nr_ue_process_mac_pdu(
    module_id_t module_idP,
    uint8_t CC_id,
    uint8_t *pduP, 
    uint16_t pdu_len, 
    uint8_t eNB_index){

    uint8_t *pdu_ptr = pduP;
    uint8_t sub_pdu_len;

    //  variable-size MAC CE(known by LCID), padding, MSG3, MAC SDU
    //  |0|1|2|3|4|5|6|7|  bit-wise
    //  |R|F|   LCID    |
    //  |       L       |

    //  variable-size MAC CE(known by LCID), padding, MSG3, MAC SDU
    //  |0|1|2|3|4|5|6|7|  bit-wise
    //  |R|F|   LCID    |
    //  |       L       |
    //  |       L       |

    //  fixed-size MAC CE(known by LCID), padding, MSG3
    //  |0|1|2|3|4|5|6|7|  bit-wise
    //  |R|R|   LCID    |

    //  LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits;
    //  L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field;
    //  F: lenght of L is 8 or 16 bits wide
    //  R: Reserved bit, set to zero.

    
    while (!done) {

        switch(((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID){
            //  Control element
            case DL_SCH_LCID_PADDING:
                done = 1;
                //  end of MAC PDU, there is nothing right after padding
                break;

            //  MAC SDU

            default:
                printf("[MAC] get lcid: %d which not support yet\n", ((NR_MAC_SUBHEADER_FIXED *)buf_ptr)->LCID);
                break;
        }
        pdu_ptr += sub_pdu_len;
    }
}