if4_tools.c 13.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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.0  (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
 */
21 22 23

/*! \file PHY/LTE_TRANSPORT/if4_tools.c
* \brief 
24
* \author S. Sandeep Kumar, Raymond Knopp
25 26 27
* \date 2016
* \version 0.1
* \company Eurecom
28
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr 
29 30 31 32
* \note
* \warning
*/

33
#include "PHY/defs.h"
34
#include "PHY/TOOLS/alaw_lut.h"
35
#include "PHY/extern.h"
36

37 38
//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
39
#include "UTIL/LOG/vcd_signal_dumper.h"
40

41
void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) {
42
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
43 44 45
  int32_t **txdataF      = (eNB->CC_id==0) ? eNB->common_vars.txdataF[0] : PHY_vars_eNB_g[0][0]->common_vars.txdataF[0];
  int32_t **rxdataF      = eNB->common_vars.rxdataF[0];
  int16_t **rxsigF       = eNB->prach_vars.rxsigF;  
46
  void *tx_buffer        = eNB->ifbuffer.tx[subframe&1];
47
  void *tx_buffer_prach  = eNB->ifbuffer.tx_prach;
48
      
49
  uint16_t symbol_id=0, element_id=0;
50
  uint16_t db_fulllength, db_halflength; 
51
  int slotoffsetF=0, blockoffsetF=0; 
52

53
  uint16_t *data_block=NULL, *i=NULL;
54

55 56 57
  IF4p5_header_t *packet_header=NULL;
  eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);

58 59
  
  if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );   
60 61

  if (packet_type == IF4p5_PDLFFT) {
62 63
    db_fulllength = 12*fp->N_RB_DL;
    db_halflength = (db_fulllength)>>1;
64
    slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
65
    blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; 
66

67

68 69 70 71 72 73 74 75
    if (eth->flags == ETH_RAW_IF4p5_MODE) {
      packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
      data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
    } else {
      packet_header = (IF4p5_header_t *)(tx_buffer);
      data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t);
    }    
    gen_IF4p5_dl_header(packet_header, frame, subframe);
76 77
		    
    for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
78
      if (eNB->CC_id==1) LOG_I(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,frame,subframe,symbol_id);
79
      
80
      for (element_id=0; element_id<db_halflength; element_id++) {
81
        i = (uint16_t*) &txdataF[eNB->CC_id][blockoffsetF+element_id];
82 83
        data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);

84
        i = (uint16_t*) &txdataF[eNB->CC_id][slotoffsetF+element_id];
85
        data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);        
86 87
      }
				 		
88 89
      packet_header->frame_status &= ~(0x000f<<26);
      packet_header->frame_status |= (symbol_id&0x000f)<<26; 
90
			
91
      if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
92
                                        symbol_id,
93
                                        &tx_buffer,
94 95
                                        db_fulllength,
      			                            1,
96 97
                                        IF4p5_PDLFFT)) < 0) {
        perror("ETHERNET write for IF4p5_PDLFFT\n");
98
      }
99 100 101
      
      slotoffsetF  += fp->ofdm_symbol_size;
      blockoffsetF += fp->ofdm_symbol_size;    
102
    }
103 104
  } else if ((packet_type == IF4p5_PULFFT)||
	     (packet_type == IF4p5_PULTICK)){
105 106
    db_fulllength = 12*fp->N_RB_UL;
    db_halflength = (db_fulllength)>>1;
Sandeep Kumar's avatar
Sandeep Kumar committed
107
    slotoffsetF = 1;
108
    blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; 
109

110 111 112 113 114 115 116
    if (eth->flags == ETH_RAW_IF4p5_MODE) {
      packet_header = (IF4p5_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
      data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
    } else {
      packet_header = (IF4p5_header_t *)(tx_buffer);
      data_block = (uint16_t*)(tx_buffer + sizeof_IF4p5_header_t);
    }
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe);

    if (packet_type == IF4p5_PULFFT) {
      for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {			
	LOG_D(PHY,"IF4p5_PULFFT: frame %d, subframe %d, symbol %d\n",frame,subframe,symbol_id);
	for (element_id=0; element_id<db_halflength; element_id++) {
	  i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id];
	  data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
	  
	  i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
	  data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);        
	}
       	
	packet_header->frame_status &= ~(0x000f<<26);
	packet_header->frame_status |= (symbol_id&0x000f)<<26; 
	
	if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
					  symbol_id,
					  &tx_buffer,
					  db_fulllength,
					  1,
					  IF4p5_PULFFT)) < 0) {
	  perror("ETHERNET write for IF4p5_PULFFT\n");
	}
	
	slotoffsetF  += fp->ofdm_symbol_size;
	blockoffsetF += fp->ofdm_symbol_size;
      }    
    }
    else {
147
      if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
148 149 150
					0,
					&tx_buffer,
					0,
151
					1,
152 153
					IF4p5_PULTICK)) < 0) {
	perror("ETHERNET write for IF4p5_PULFFT\n");
154
      }
155
    }
156
  } else if (packet_type == IF4p5_PRACH) {
157
    // FIX: hard coded prach samples length
158
    LOG_D(PHY,"IF4p5_PRACH: frame %d, subframe %d\n",frame,subframe);
159 160
    db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES;
    
161
    if (eth->flags == ETH_RAW_IF4p5_MODE) {
162
      packet_header = (IF4p5_header_t *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES);
163 164
      data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t);
    } else {
165 166
      packet_header = (IF4p5_header_t *)(tx_buffer_prach);
      data_block = (uint16_t*)(tx_buffer_prach + sizeof_IF4p5_header_t);
167 168 169 170
    }  
    gen_IF4p5_prach_header(packet_header, frame, subframe);

    if (eth->flags == ETH_RAW_IF4p5_MODE) {
171
      memcpy((int16_t*)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
172
             (&rxsigF[0][k]), 
173
             PRACH_BLOCK_SIZE_BYTES);
174
    } else {
175
      memcpy((int16_t*)(tx_buffer_prach + sizeof_IF4p5_header_t),
176
             (&rxsigF[0][k]),
177
             PRACH_BLOCK_SIZE_BYTES);
178
    }
179 180

    if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
181
                                      symbol_id,
182
                                      &tx_buffer_prach,
183 184
                                      db_fulllength,
                                      1,
185 186
                                      IF4p5_PRACH)) < 0) {
      perror("ETHERNET write for IF4p5_PRACH\n");
187
    }      
188
  } else {    
189
    AssertFatal(1==0, "send_IF4p5 - Unknown packet_type %x", packet_type);     
190
  }
191

192
  if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );  
193
  return;  		    
194
}
195

196

197
void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_type, uint32_t *symbol_number) {
198 199 200
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
  int32_t **txdataF = eNB->common_vars.txdataF[0];
  int32_t **rxdataF = eNB->common_vars.rxdataF[0];
201
  int16_t **rxsigF = eNB->prach_vars.rxsigF;  
202
  void *rx_buffer = eNB->ifbuffer.rx;
203 204

  uint16_t element_id;
205
  uint16_t db_fulllength, db_halflength; 
Sandeep Kumar's avatar
Sandeep Kumar committed
206
  int slotoffsetF=0, blockoffsetF=0; 
207
  eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
208

209
  if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );   
210
  
211
  if (eNB->node_function == NGFI_RRU_IF4p5) {
212
    db_fulllength = (12*fp->N_RB_DL); 
213
  } else {
214
    db_fulllength = (12*fp->N_RB_UL);     
215 216 217
  }  
  db_halflength = db_fulllength>>1;

218
  IF4p5_header_t *packet_header=NULL;
219
  uint16_t *data_block=NULL, *i=NULL;
220
     
221
  if (eNB->ifdevice.trx_read_func(&eNB->ifdevice,
222
                                  (int64_t*) packet_type,
223 224
                                  &rx_buffer,
                                  db_fulllength,
225
                                  0) < 0) {
226 227
    perror("ETHERNET read");
  }
228 229 230 231 232 233 234 235

  if (eth->flags == ETH_RAW_IF4p5_MODE) {
    packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
    data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t);
  } else {
    packet_header = (IF4p5_header_t*) (rx_buffer);
    data_block = (uint16_t*) (rx_buffer+sizeof_IF4p5_header_t);
  }
236

luhan wang's avatar
luhan wang committed
237 238

  
239
  *frame = ((packet_header->frame_status)>>6)&0xffff;
240
  *subframe = ((packet_header->frame_status)>>22)&0x000f;
luhan wang's avatar
luhan wang committed
241

242
  *packet_type = packet_header->sub_type; 
Raymond Knopp's avatar
Raymond Knopp committed
243 244


245
  if (*packet_type == IF4p5_PDLFFT) {          
Sandeep Kumar's avatar
Sandeep Kumar committed
246 247
    *symbol_number = ((packet_header->frame_status)>>26)&0x000f;         

248
    LOG_D(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);
249

Sandeep Kumar's avatar
Sandeep Kumar committed
250
    slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
251 252
    blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; 
        
253
    for (element_id=0; element_id<db_halflength; element_id++) {
254 255 256
      i = (uint16_t*) &txdataF[0][blockoffsetF+element_id];
      *i = alaw2lin[ (data_block[element_id] & 0xff) ]; 
      *(i+1) = alaw2lin[ (data_block[element_id]>>8) ];
257

258 259 260
      i = (uint16_t*) &txdataF[0][slotoffsetF+element_id];
      *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ]; 
      *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
261
    }
Sandeep Kumar's avatar
Sandeep Kumar committed
262
		        
263
  } else if (*packet_type == IF4p5_PULFFT) {         
264
    *symbol_number = ((packet_header->frame_status)>>26)&0x000f;         
Sandeep Kumar's avatar
Sandeep Kumar committed
265

266 267
    if (eNB->CC_id==1) LOG_I(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number);

Sandeep Kumar's avatar
Sandeep Kumar committed
268
    slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + 1;
269
    blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; 
270 271
    
    for (element_id=0; element_id<db_halflength; element_id++) {
272 273 274
      i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id];
      *i = alaw2lin[ (data_block[element_id] & 0xff) ]; 
      *(i+1) = alaw2lin[ (data_block[element_id]>>8) ];
275

276 277 278
      i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
      *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ]; 
      *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
279 280
    }
		
281
  } else if (*packet_type == IF4p5_PRACH) {    
Raymond.Knopp's avatar
Raymond.Knopp committed
282 283
    if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe);

Sandeep Kumar's avatar
Sandeep Kumar committed
284
    // FIX: hard coded prach samples length
285
    db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES;
286 287 288 289

    if (eth->flags == ETH_RAW_IF4p5_MODE) {		
      memcpy((&rxsigF[0][0]), 
             (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t), 
290
             PRACH_BLOCK_SIZE_BYTES);
291 292 293
    } else {
      memcpy((&rxsigF[0][0]),
             (int16_t*) (rx_buffer+sizeof_IF4p5_header_t),
294
             PRACH_BLOCK_SIZE_BYTES);
295 296
    }

297
  } else {
298
    AssertFatal(1==0, "recv_IF4p5 - Unknown packet_type %x", *packet_type);            
299
  }
300

301
  if (eNB->CC_id==0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );     
302
  return;   
303 304
}

305

306 307 308
void gen_IF4p5_dl_header(IF4p5_header_t *dl_packet, int frame, int subframe) {      
  dl_packet->type = IF4p5_PACKET_TYPE; 
  dl_packet->sub_type = IF4p5_PDLFFT;
309

310
  dl_packet->rsvd = 0;
311 312
  
  // Set frame status
Sandeep Kumar's avatar
Sandeep Kumar committed
313 314 315
  dl_packet->frame_status = 0;
  dl_packet->frame_status |= (frame&0xffff)<<6;
  dl_packet->frame_status |= (subframe&0x000f)<<22;
316 317
}

318

319
void gen_IF4p5_ul_header(IF4p5_header_t *ul_packet, uint16_t packet_subtype, int frame, int subframe) {  
Raymond Knopp's avatar
Raymond Knopp committed
320

321
  ul_packet->type = IF4p5_PACKET_TYPE; 
322
  ul_packet->sub_type = packet_subtype;
323

324
  ul_packet->rsvd = 0;
325 326
  
  // Set frame status
Sandeep Kumar's avatar
Sandeep Kumar committed
327 328 329
  ul_packet->frame_status = 0;
  ul_packet->frame_status |= (frame&0xffff)<<6;
  ul_packet->frame_status |= (subframe&0x000f)<<22;
330 331
}

332

333 334 335
void gen_IF4p5_prach_header(IF4p5_header_t *prach_packet, int frame, int subframe) {
  prach_packet->type = IF4p5_PACKET_TYPE; 
  prach_packet->sub_type = IF4p5_PRACH;
336

337
  prach_packet->rsvd = 0;
338 339
  
  // Set LTE Prach configuration
Sandeep Kumar's avatar
Sandeep Kumar committed
340 341 342
  prach_packet->frame_status = 0;
  prach_packet->frame_status |= (frame&0xffff)<<6;
  prach_packet->frame_status |= (subframe&0x000f)<<22;
343
} 
344 345


346
void malloc_IF4p5_buffer(PHY_VARS_eNB *eNB) {
347
  // Keep the size large enough 
348
  eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv);
349 350
  int i;

351
  if (eth->flags == ETH_RAW_IF4p5_MODE) {
352 353
    for (i=0;i<10;i++)
      eNB->ifbuffer.tx[i]       = malloc(RAW_IF4p5_PRACH_SIZE_BYTES);
354 355
    eNB->ifbuffer.tx_prach = malloc(RAW_IF4p5_PRACH_SIZE_BYTES);
    eNB->ifbuffer.rx       = malloc(RAW_IF4p5_PRACH_SIZE_BYTES); 
356 357 358
  } else {
    for (i=0;i<10;i++)
      eNB->ifbuffer.tx[i]       = malloc(UDP_IF4p5_PRACH_SIZE_BYTES);
359 360
    eNB->ifbuffer.tx_prach = malloc(UDP_IF4p5_PRACH_SIZE_BYTES);
    eNB->ifbuffer.rx       = malloc(UDP_IF4p5_PRACH_SIZE_BYTES);
361
  }
362
}