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