* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / app / src / common.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19 #include <assert.h>
20 #include <err.h>
21 #include <arpa/inet.h>
22 #include <sys/time.h>
23 #include <time.h>
24 #include <immintrin.h>
25 #include "common.h"
26 #include "xran_fh_o_du.h"
27 #include "xran_pkt.h"
28 #include "xran_pkt_up.h"
29 #include "xran_cp_api.h"
30 #include "xran_up_api.h"
31
32 #include "xran_mlog_lnx.h"
33
34 extern enum app_state state;
35 struct o_xu_buffers* p_o_xu_buff[XRAN_PORTS_NUM] = {NULL, NULL, NULL, NULL};
36
37 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
38 uint16_t nLteNumRbsPerSymF1[1][4] =
39 {
40     //  5MHz    10MHz   15MHz   20 MHz
41         {25,    50,     75,     100},         // Numerology 0 (15KHz)
42 };
43
44 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
45 uint16_t nNumRbsPerSymF1[3][13] =
46 {
47     //  5MHz    10MHz   15MHz   20 MHz  25 MHz  30 MHz  40 MHz  50MHz   60 MHz  70 MHz  80 MHz   90 MHz  100 MHz
48         {25,    52,     79,     106,    133,    160,    216,    270,    0,         0,      0,      0,      0},         // Numerology 0 (15KHz)
49         {11,    24,     38,     51,     65,     78,     106,    133,    162,       0,    217,    245,    273},         // Numerology 1 (30KHz)
50         {0,     11,     18,     24,     31,     38,     51,     65,     79,        0,    107,    121,    135}          // Numerology 2 (60KHz)
51 };
52
53 // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
54 uint16_t nNumRbsPerSymF2[2][4] =
55 {
56     //  50Mhz  100MHz  200MHz   400MHz
57         {66,    132,    264,     0},        // Numerology 2 (60KHz)
58         {32,    66,     132,     264}       // Numerology 3 (120KHz)
59 };
60
61 // 38.211 - Table 4.2.1
62 uint16_t nSubCarrierSpacing[5] =
63 {
64     15,     // mu = 0
65     30,     // mu = 1
66     60,     // mu = 2
67     120,    // mu = 3
68     240     // mu = 4
69 };
70
71 // TTI interval in us (slot duration)
72 uint16_t nTtiInterval[4] =
73 {
74     1000,     // mu = 0
75     500,     // mu = 1
76     250,     // mu = 2
77     125,     // mu = 3
78 };
79
80
81 // F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
82 uint16_t nCpSizeF1[3][13][2] =
83 {
84     //    5MHz      10MHz      15MHz       20 MHz      25 MHz     30 MHz      40 MHz       50MHz       60 MHz      70 MHz     80 MHz     90 MHz     100 MHz
85         {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288},     {0, 0},     {0, 0},     {0, 0},     {0, 0},     {0, 0}},        // Numerology 0 (15KHz)
86         {{22, 18}, {44, 36},   {66, 54},   {88, 72},   {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}},       // Numerology 1 (30KHz)
87         {  {0, 0}, {26, 18},   {39, 27},   {52, 36},   {52, 36},   {78, 54},  {104, 72},  {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}},       // Numerology 2 (60KHz)
88 };
89
90 // F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
91 int16_t nCpSizeF2[2][4][2] =
92 {
93     //    50Mhz    100MHz      200MHz     400MHz
94         {  {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
95         {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
96 };
97
98 uint32_t gLocMaxSlotNum;
99
100 static uint16_t g_NumSlotTDDLoop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
101 static uint16_t g_NumDLSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
102 static uint16_t g_NumULSymSp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
103 static uint8_t g_SlotType[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
104 float g_UlRate[XRAN_MAX_SECTOR_NR] = {0.0};
105 float g_DlRate[XRAN_MAX_SECTOR_NR] = {0.0};
106
107 uint32_t app_xran_get_tti_interval(uint8_t nMu)
108 {
109     if (nMu < 4)
110     {
111         return nTtiInterval[nMu];
112     }
113     else
114     {
115         printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
116     }
117
118     return 0;
119 }
120
121 uint32_t app_xran_get_scs(uint8_t nMu)
122 {
123     if (nMu <= 3)
124     {
125         return nSubCarrierSpacing[nMu];
126     }
127     else
128     {
129         printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
130     }
131
132     return 0;
133 }
134
135
136
137
138 //-------------------------------------------------------------------------------------------
139 /** @ingroup group_nr5g_source_phy_common
140  *
141  *  @param[in]   nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz,  1: 30khz,  2: 60khz 3: 120khz, 4: 240khz
142  *  @param[in]   nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
143  *  @param[in]   nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
144  *
145  *  @return  Number of RBs in cell
146  *
147  *  @description
148  *  Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
149  *
150 **/
151 //-------------------------------------------------------------------------------------------
152 uint16_t app_xran_get_num_rbs(uint8_t ranTech, uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
153 {
154     uint32_t error = 1;
155     uint16_t numRBs = 0;
156
157     if (ranTech == XRAN_RAN_LTE) {
158         switch(nBandwidth)
159         {
160             case PHY_BW_5_0_MHZ:
161                 numRBs = nLteNumRbsPerSymF1[nNumerology][0];
162                 error = 0;
163             break;
164             case PHY_BW_10_0_MHZ:
165                 numRBs = nLteNumRbsPerSymF1[nNumerology][1];
166                 error = 0;
167             break;
168             case PHY_BW_15_0_MHZ:
169                 numRBs = nLteNumRbsPerSymF1[nNumerology][2];
170                 error = 0;
171             break;
172             case PHY_BW_20_0_MHZ:
173                 numRBs = nLteNumRbsPerSymF1[nNumerology][3];
174                 error = 0;
175             break;
176             default:
177                 error = 1;
178             break;
179         }
180     } else if (nAbsFrePointA <= 6000000) {
181         // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
182         if (nNumerology < 3)
183         {
184             switch(nBandwidth)
185             {
186                 case PHY_BW_5_0_MHZ:
187                     numRBs = nNumRbsPerSymF1[nNumerology][0];
188                     error = 0;
189                 break;
190                 case PHY_BW_10_0_MHZ:
191                     numRBs = nNumRbsPerSymF1[nNumerology][1];
192                     error = 0;
193                 break;
194                 case PHY_BW_15_0_MHZ:
195                     numRBs = nNumRbsPerSymF1[nNumerology][2];
196                     error = 0;
197                 break;
198                 case PHY_BW_20_0_MHZ:
199                     numRBs = nNumRbsPerSymF1[nNumerology][3];
200                     error = 0;
201                 break;
202                 case PHY_BW_25_0_MHZ:
203                     numRBs = nNumRbsPerSymF1[nNumerology][4];
204                     error = 0;
205                 break;
206                 case PHY_BW_30_0_MHZ:
207                     numRBs = nNumRbsPerSymF1[nNumerology][5];
208                     error = 0;
209                 break;
210                 case PHY_BW_40_0_MHZ:
211                     numRBs = nNumRbsPerSymF1[nNumerology][6];
212                     error = 0;
213                 break;
214                 case PHY_BW_50_0_MHZ:
215                     numRBs = nNumRbsPerSymF1[nNumerology][7];
216                     error = 0;
217                 break;
218                 case PHY_BW_60_0_MHZ:
219                     numRBs = nNumRbsPerSymF1[nNumerology][8];
220                     error = 0;
221                 break;
222                 case PHY_BW_70_0_MHZ:
223                     numRBs = nNumRbsPerSymF1[nNumerology][9];
224                     error = 0;
225                 break;
226                 case PHY_BW_80_0_MHZ:
227                     numRBs = nNumRbsPerSymF1[nNumerology][10];
228                     error = 0;
229                 break;
230                 case PHY_BW_90_0_MHZ:
231                     numRBs = nNumRbsPerSymF1[nNumerology][11];
232                     error = 0;
233                 break;
234                 case PHY_BW_100_0_MHZ:
235                     numRBs = nNumRbsPerSymF1[nNumerology][12];
236                     error = 0;
237                 break;
238                 default:
239                     error = 1;
240                 break;
241             }
242         }
243     }
244     else
245     {
246         if ((nNumerology >= 2) && (nNumerology <= 3))
247         {
248             // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
249             switch(nBandwidth)
250             {
251                 case PHY_BW_50_0_MHZ:
252                     numRBs = nNumRbsPerSymF2[nNumerology-2][0];
253                     error = 0;
254                 break;
255                 case PHY_BW_100_0_MHZ:
256                     numRBs = nNumRbsPerSymF2[nNumerology-2][1];
257                     error = 0;
258                 break;
259                 case PHY_BW_200_0_MHZ:
260                     numRBs = nNumRbsPerSymF2[nNumerology-2][2];
261                     error = 0;
262                 break;
263                 case PHY_BW_400_0_MHZ:
264                     numRBs = nNumRbsPerSymF2[nNumerology-2][3];
265                     error = 0;
266                 break;
267                 default:
268                     error = 1;
269                 break;
270             }
271         }
272     }
273
274
275     if (error)
276     {
277         printf("ERROR: %s: RAN[%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA);
278     }
279     else
280     {
281         printf("%s: RAN [%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA, numRBs);
282     }
283
284     return numRBs;
285 }
286
287 //-------------------------------------------------------------------------------------------
288 /** @ingroup phy_cal_nrarfcn
289  *
290  *  @param[in]   center frequency
291  *
292  *  @return  NR-ARFCN
293  *
294  *  @description
295  *  This calculates NR-ARFCN value according to center frequency
296  *
297 **/
298 //-------------------------------------------------------------------------------------------
299 uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq)
300 {
301     uint32_t nDeltaFglobal,nFoffs,nNoffs;
302     uint32_t nNRARFCN = 0;
303
304     if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
305     {
306         nDeltaFglobal = 5;
307         nFoffs = 0;
308         nNoffs = 0;
309     }
310     else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
311     {
312         nDeltaFglobal = 15;
313         nFoffs = 3000*1000;
314         nNoffs = 600000;
315     }
316     else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
317     {
318         nDeltaFglobal = 60;
319         nFoffs = 24250080;
320         nNoffs = 2016667;
321     }
322     else
323     {
324          printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
325          return (0);
326     }
327
328     nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
329
330     printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
331     return (nNRARFCN);
332 }
333
334 int32_t app_xran_slot_limit(int32_t nSfIdx)
335 {
336     while (nSfIdx < 0) {
337         nSfIdx += gLocMaxSlotNum;
338     }
339
340     while (nSfIdx >= gLocMaxSlotNum) {
341         nSfIdx -= gLocMaxSlotNum;
342     }
343
344     return nSfIdx;
345 }
346
347 void app_xran_clear_slot_type(uint32_t nPhyInstanceId)
348 {
349     g_UlRate[nPhyInstanceId] = 0.0;
350     g_DlRate[nPhyInstanceId] = 0.0;
351     g_NumSlotTDDLoop[nPhyInstanceId] = 1;
352 }
353
354 int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig)
355 {
356     uint32_t nSlotNum, nSymNum, nVal, i;
357     uint32_t numDlSym, numUlSym, numGuardSym;
358     uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
359     char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
360
361     // nPhyInstanceId    Carrier ID
362     // nFrameDuplexType  0 = FDD 1 = TDD
363     // nTddPeriod        Tdd Periodicity
364     // psSlotConfig[80]  Slot Config Structure for nTddPeriod Slots
365
366     g_UlRate[nPhyInstanceId] = 0.0;
367     g_DlRate[nPhyInstanceId] = 0.0;
368     g_NumSlotTDDLoop[nPhyInstanceId] = nTddPeriod;
369
370     for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
371     {
372         g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
373         g_NumDLSymSp[nPhyInstanceId][i] = 0;
374         g_NumULSymSp[nPhyInstanceId][i] = 0;
375     }
376
377     if (nFrameDuplexType == XRAN_FDD)
378     {
379         for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
380         {
381             g_SlotType[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
382         }
383         g_NumSlotTDDLoop[nPhyInstanceId] = 1;
384         g_DlRate[nPhyInstanceId] = 1.0;
385         g_UlRate[nPhyInstanceId] = 1.0;
386     }
387     else
388     {
389         for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
390         {
391             numDlSym = 0;
392             numUlSym = 0;
393             numGuardSym = 0;
394             for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
395             {
396                 switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
397                 {
398                     case XRAN_SYMBOL_TYPE_DL:
399                         numDlSym++;
400                     break;
401                     case XRAN_SYMBOL_TYPE_GUARD:
402                         numGuardSym++;
403                     break;
404                     default:
405                         numUlSym++;
406                     break;
407                 }
408             }
409
410             // printf("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d]\n", nSlotNum, numDlSym, numGuardSym, numUlSym);
411
412             if ((numUlSym == 0) && (numGuardSym == 0))
413             {
414                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
415                 numDlSlots++;
416             }
417             else if ((numDlSym == 0) && (numGuardSym == 0))
418             {
419                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
420                 numUlSlots++;
421             }
422             else
423             {
424                 g_SlotType[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
425                 numSpSlots++;
426
427                 if (numDlSym)
428                 {
429                     numSpDlSlots++;
430                     g_NumDLSymSp[nPhyInstanceId][nSlotNum] = numDlSym;
431                 }
432                 if (numUlSym)
433                 {
434                     numSpUlSlots++;
435                     g_NumULSymSp[nPhyInstanceId][nSlotNum] = numUlSym;
436                 }
437             }
438
439             // printf("            numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
440         }
441
442         g_DlRate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
443         g_UlRate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
444     }
445
446     printf("set_slot_type: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
447         nPhyInstanceId, nFrameDuplexType, nTddPeriod);
448
449     printf("DLRate[%f] ULRate[%f]\n", g_DlRate[nPhyInstanceId], g_UlRate[nPhyInstanceId]);
450
451     nVal = (g_NumSlotTDDLoop[nPhyInstanceId] < 10) ? g_NumSlotTDDLoop[nPhyInstanceId] : 10;
452
453     printf("SlotPattern:\n");
454     printf("Slot:   ");
455     for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
456     {
457         printf("%d    ", nSlotNum);
458     }
459     printf("\n");
460
461     printf("  %3d   ", 0);
462     for (nSlotNum = 0, i = 0; nSlotNum < g_NumSlotTDDLoop[nPhyInstanceId]; nSlotNum++)
463     {
464         printf("%s   ", sSlotPattern[g_SlotType[nPhyInstanceId][nSlotNum]]);
465         i++;
466         if ((i == 10) && ((nSlotNum+1) < g_NumSlotTDDLoop[nPhyInstanceId]))
467         {
468             printf("\n");
469             printf("  %3d   ", nSlotNum);
470             i = 0;
471         }
472     }
473     printf("\n\n");
474
475     return 0;
476 }
477
478 int32_t app_xran_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
479 {
480     int32_t nSfIdxMod, nSfType, ret = 0;
481
482     nSfIdxMod = app_xran_slot_limit(nSlotdx) % ((g_NumSlotTDDLoop[nCellIdx] > 0) ? g_NumSlotTDDLoop[nCellIdx]: 1);
483     nSfType = g_SlotType[nCellIdx][nSfIdxMod];
484
485     if (nSfType == nType)
486     {
487         ret = 1;
488     }
489     else if (nSfType == XRAN_SLOT_TYPE_SP)
490     {
491         if ((nType == XRAN_SLOT_TYPE_DL) && g_NumDLSymSp[nCellIdx][nSfIdxMod])
492         {
493             ret = 1;
494         }
495
496         if ((nType == XRAN_SLOT_TYPE_UL) && g_NumULSymSp[nCellIdx][nSfIdxMod])
497         {
498             ret = 1;
499         }
500     }
501     else if (nSfType == XRAN_SLOT_TYPE_FDD)
502     {
503         ret = 1;
504     }
505
506     return ret;
507 }
508
509
510
511 void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
512 {
513     if (size)
514     {
515         if (filename && bufname)
516         {
517             FILE           *file;
518             printf("Storing %s to file %s: ", bufname, filename);
519             file = fopen(filename, "wb");
520             if (file == NULL)
521             {
522                 printf("can't open file %s!!!", filename);
523             }
524             else
525             {
526                 uint32_t             num;
527                 num = fwrite(pBuffer, buffers_num, size, file);
528                 fflush(file);
529                 fclose(file);
530                 printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, size, num);
531             }
532             printf(" \n");
533         }
534         else
535         {
536             printf(" the file name, buffer name are not set!!!");
537         }
538     }
539     else
540     {
541         printf(" the %s is free: size = %d bytes!!!", bufname, size);
542     }
543 }
544
545 int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
546 {
547     unsigned int  file_size = 0;
548     int  num= 0;
549
550     if (size)
551     {
552         if (filename && bufname)
553         {
554             FILE           *file;
555             printf("Loading file %s to  %s: ", filename, bufname);
556             file = fopen(filename, "rb");
557
558
559             if (file == NULL)
560             {
561                 printf("can't open file %s!!!", filename);
562                 exit(-1);
563             }
564             else
565             {
566                 fseek(file, 0, SEEK_END);
567                 file_size = ftell(file);
568                 fseek(file, 0, SEEK_SET);
569
570                 if ((file_size > size) || (file_size == 0))
571                     file_size = size;
572
573                 printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
574
575                 num = fread(pBuffer, buffers_num, size, file);
576                 fflush(file);
577                 fclose(file);
578                 printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
579             }
580             printf(" \n");
581
582         }
583         else
584         {
585             printf(" the file name, buffer name are not set!!!");
586         }
587     }
588     else
589     {
590         printf(" the %s is free: size = %d bytes!!!", bufname, size);
591     }
592     return num;
593 }
594
595
596 void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
597 {
598     unsigned int i;
599     int ret = 0;
600     if (pBuffer == NULL)
601         return;
602
603     if (size)
604     {
605         if (filename && bufname)
606         {
607             FILE           *file;
608             printf("Storing %s to file %s: ", bufname, filename);
609             file = fopen(filename, "w");
610             if (file == NULL)
611             {
612                 printf("can't open file %s!!!", filename);
613                 exit(-1);
614             }
615             else
616             {
617                 uint32_t num = 0;
618
619                 signed short *ptr = (signed short*)pBuffer;
620                 for (i = 0; i < (size/((unsigned int)sizeof(signed short) /** 2 * 2 * 2*/)); i = i + 2)
621                 {
622 #ifndef CSCOPE_DEBUG
623                     ret = fprintf(file,"%d %d\n", ptr[i], ptr[i + 1]);
624 #else
625                     ret = fprintf(file,"%d %d ", ptr[i], ptr[i + 1]);
626                     /*      I data => Ramp data, from 1 to 792.
627                             Q data => Contains time information of the current symbol:
628                             Bits [15:14] = Antenna-ID
629                             Bits [13:12] = \9300\94
630                             Bits [11:8]  = Subframe-ID
631                             Bits [7:4]   = Slot-ID
632                             Bits [3:0]   = Symbol-ID */
633                             fprintf(file, "0x%04x: ant %d Subframe-ID %d Slot-ID %d Symbol-ID %d\n",
634                                         ptr[i + 1], (ptr[i + 1]>>14) & 0x3,  (ptr[i + 1]>>8) & 0xF,  (ptr[i + 1]>>4) & 0xF, (ptr[i + 1]>>0) & 0xF);
635 #endif
636                     if (ret < 0)
637                     {
638                         printf("fprintf %d\n", ret);
639                         fclose(file);
640                         break;
641                     }
642                     num++;
643                 }
644                 fflush(file);
645                 fclose(file);
646                 printf("from addr (0x%lx) size (%d) IQ num (%d)", (uint64_t)pBuffer, size, num);
647             }
648             printf(" \n");
649         }
650         else
651         {
652             printf(" the file name, buffer name are not set!!!");
653         }
654     }
655     else
656     {
657         printf(" the %s is free: size = %d bytes!!!", bufname, size);
658     }
659 }
660