From Lei Chen:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Feb 2012 08:57:40 +0000 (08:57 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 23 Feb 2012 08:57:40 +0000 (08:57 +0000)
a patch to support decode FDD_CELL_INFORMATION of "UTRAN FDD Description" in packet-gsm_rlcmac.c

https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6856

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@41149 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-csn1.c
epan/dissectors/packet-csn1.h
epan/dissectors/packet-gsm_a_rr.c
epan/dissectors/packet-gsm_rlcmac.c
epan/dissectors/packet-gsm_rlcmac.h

index 8d8f685..87209e8 100644 (file)
@@ -42,6 +42,7 @@
 #define STANDARD_TAG 1
 #define REVERSED_TAG 0
 
+
 static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
 
 
@@ -1539,7 +1540,13 @@ csnStreamDissector(proto_tree *tree, csnStream_t* ar, const CSN_DESCR* pDescr, t
 
       case CSN_CALLBACK:
       {
-        return ProcessError(tree, tvb, bit_offset,"csnStreamDissector Callback not implemented", -1, pDescr);
+        guint16  no_of_bits;
+        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->descr.ptr;
+
+        no_of_bits = callback(tree, tvb, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset), bit_offset, ett_csn1);
+        bit_offset += no_of_bits;
+        
+        pDescr++;
         break;
       }
 
index 672f162..8a5d8a1 100644 (file)
@@ -66,6 +66,8 @@ typedef struct
 } csnStream_t;
 
 typedef gint16 (*StreamSerializeFcn_t)(proto_tree *tree, csnStream_t* ar, tvbuff_t *tvb, void* data, int ett_csn1);
+typedef CSN_CallBackStatus_t (*DissectorCallbackFcn_t)(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1);
+
 
 typedef enum
 {
index 4b00400..1f77a15 100644 (file)
@@ -1046,7 +1046,7 @@ static gint greatest_power_of_2_lesser_or_equal_to(gint idx)
     return j;
 }
 
-static gint f_k(gint k, gint *w, gint range)
+gint f_k(gint k, gint *w, gint range)
 {
     gint idx, n, j;
 
index 079fe0e..13b8ef9 100644 (file)
@@ -3504,12 +3504,27 @@ CSN_DESCR_BEGIN(Cell_Selection_Params_With_FreqDiff_t)
   M_TYPE       (Cell_Selection_Params_With_FreqDiff_t, Cell_SelectionParams, Cell_Selection_t),
 CSN_DESCR_END  (Cell_Selection_Params_With_FreqDiff_t)
 
+CSN_CallBackStatus_t callback_init_Cell_Selection_Params_FREQUENCY_DIFF(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    guint  i;
+    guint8 freq_diff_len = *(guint8*)param1;
+    Cell_Selection_Params_With_FreqDiff_t *pCell_Sel_Param = (Cell_Selection_Params_With_FreqDiff_t*)param2;
+
+    for( i=0; i<16; i++, pCell_Sel_Param++ )
+    {
+        pCell_Sel_Param->FREQ_DIFF_LENGTH = freq_diff_len;
+    }
+
+    return 0;
+}
+
 static const
 CSN_DESCR_BEGIN(NeighbourCellParameters_t)
   M_UINT       (NeighbourCellParameters_t,  START_FREQUENCY,  10, &hf_neighbourcellparameters_start_frequency),
   M_TYPE       (NeighbourCellParameters_t, Cell_Selection, Cell_Selection_t),
   M_UINT       (NeighbourCellParameters_t,  NR_OF_REMAINING_CELLS,  4, &hf_neighbourcellparameters_nr_of_remaining_cells),
   M_UINT_OFFSET(NeighbourCellParameters_t, FREQ_DIFF_LENGTH, 3, 1),/* offset 1 */
+  M_CALLBACK   (NeighbourCellParameters_t, (void*)callback_init_Cell_Selection_Params_FREQUENCY_DIFF, FREQ_DIFF_LENGTH, Cell_Selection_Params_With_FreqDiff),
   M_VAR_TARRAY (NeighbourCellParameters_t, Cell_Selection_Params_With_FreqDiff, Cell_Selection_Params_With_FreqDiff_t, NR_OF_REMAINING_CELLS),
 CSN_DESCR_END  (NeighbourCellParameters_t)
 
@@ -3607,6 +3622,22 @@ static const CSN_DESCR_BEGIN(CellSelectionParamsWithFreqDiff_t)
   M_TYPE       (CellSelectionParamsWithFreqDiff_t, CellSelectionParams, Cell_Selection_2_t),
 CSN_DESCR_END  (CellSelectionParamsWithFreqDiff_t)
 
+
+CSN_CallBackStatus_t callback_init_Cell_Sel_Param_2_FREQUENCY_DIFF(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    guint  i;
+    guint8 freq_diff_len = *(guint8*)param1;
+    CellSelectionParamsWithFreqDiff_t *pCell_Sel_Param = (CellSelectionParamsWithFreqDiff_t*)param2;
+
+    for( i=0; i<16; i++, pCell_Sel_Param++ )
+    {
+        pCell_Sel_Param->FREQ_DIFF_LENGTH = freq_diff_len;
+    }
+
+    return 0;
+}
+
+
 static const
 CSN_DESCR_BEGIN(Add_Frequency_list_t)
   M_UINT       (Add_Frequency_list_t,  START_FREQUENCY,  10, &hf_add_frequency_list_start_frequency),
@@ -3618,6 +3649,8 @@ CSN_DESCR_BEGIN(Add_Frequency_list_t)
   M_UINT       (Add_Frequency_list_t,  NR_OF_FREQUENCIES,  5, &hf_add_frequency_list_nr_of_frequencies),
   M_UINT_OFFSET(Add_Frequency_list_t, FREQ_DIFF_LENGTH, 3, 1),/*offset 1*/
 
+  M_CALLBACK   (Add_Frequency_list_t, (void*)callback_init_Cell_Sel_Param_2_FREQUENCY_DIFF, FREQ_DIFF_LENGTH, CellSelectionParamsWithFreqDiff),
+
   M_VAR_TARRAY (Add_Frequency_list_t, CellSelectionParamsWithFreqDiff, CellSelectionParamsWithFreqDiff_t, NR_OF_FREQUENCIES),
 CSN_DESCR_END  (Add_Frequency_list_t)
 
@@ -3787,13 +3820,97 @@ CSN_DESCR_BEGIN(CDMA2000_Description_t)
   CSN_ERROR    (CDMA2000_Description_t, "Not Implemented", CSN_ERROR_STREAM_NOT_SUPPORTED),
 CSN_DESCR_END  (CDMA2000_Description_t)
 
+const static guint8 NR_OF_FDD_CELLS_map[32] = {0, 10, 19, 28, 36, 44, 52, 60, 67, 74, 81, 88, 95, 102, 109, 116, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+CSN_CallBackStatus_t callback_UTRAN_FDD_map_NrOfFrequencies(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{   /* TS 44.060 Table 11.2.9b.2.a */
+    guint8 * pNrOfCells = (guint8*)param1;
+    guint8 * pBitsInCellInfo = (guint8*)param2;
+
+    if( *pNrOfCells < 32 )
+    {
+        *pBitsInCellInfo = NR_OF_FDD_CELLS_map[*pNrOfCells];
+    }
+    else
+    {
+        *pBitsInCellInfo = 0;
+    }
+
+    return 0;
+}
+
+CSN_CallBackStatus_t callback_UTRAN_FDD_compute_FDD_CELL_INFORMATION(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    proto_item   *ti;
+    proto_tree   *subtree;
+    UTRAN_FDD_NeighbourCells_t * pUtranFddNcell = (UTRAN_FDD_NeighbourCells_t*)param1;
+    gint xdd_cell_info, wsize, nwi, jwi, w[64], i, iused;
+    gint curr_bit_offset, idx;
+
+    curr_bit_offset = bit_offset;
+    idx = pUtranFddNcell->BitsInCellInfo;
+
+    if( idx > 0 )
+    {
+        ti = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, 1,  "FDD_CELL_INFORMATION: ");
+        subtree = proto_item_add_subtree(ti, ett_csn1);
+        
+        if (pUtranFddNcell->Indic0)
+        {
+            proto_tree_add_text(tree,tvb, curr_bit_offset>>3, 0, "Scrambling Code: %d", 0);
+            proto_tree_add_text(tree,tvb, curr_bit_offset>>3, 0, "Diversity: %d", 0);
+        }
+
+        if (idx)
+        {
+            wsize = 10;
+            nwi = 1;
+            jwi = 0;
+            i = 1;
+
+            while (idx > 0)
+            {
+                w[i] = tvb_get_bits(tvb, curr_bit_offset, wsize, ENC_BIG_ENDIAN);
+                curr_bit_offset += wsize;
+                idx -= wsize;
+                if (w[i] == 0)
+                {
+                    idx = 0;
+                    break;
+                }
+                if (++jwi==nwi)
+                {
+                    jwi = 0;
+                    nwi <<= 1;
+                    wsize--;
+                }
+                i++;
+            }
+            if (idx < 0)
+            {
+                curr_bit_offset += idx;
+            }
+            iused = i-1;
+
+            for (i=1; i <= iused; i++)
+            {
+                xdd_cell_info = f_k(i, w, 1024);
+                proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, 0, "Scrambling Code: %d", xdd_cell_info & 0x01FF);
+                proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, 0, "Diversity: %d", (xdd_cell_info >> 9) & 0x01);
+            }
+        }
+    }
+
+    return curr_bit_offset - bit_offset;
+}
+
+
+
 static const
 CSN_DESCR_BEGIN(UTRAN_FDD_NeighbourCells_t)
   M_UINT       (UTRAN_FDD_NeighbourCells_t,  ZERO,      1, &hf_utran_fdd_neighbourcells_zero),
   M_UINT       (UTRAN_FDD_NeighbourCells_t,  UARFCN,   14, &hf_utran_fdd_neighbourcells_uarfcn),
   M_UINT       (UTRAN_FDD_NeighbourCells_t,  Indic0,      1, &hf_utran_fdd_neighbourcells_indic0),
   M_UINT       (UTRAN_FDD_NeighbourCells_t,  NrOfCells,   5, &hf_utran_fdd_neighbourcells_nrofcells),
-/*  M_CALLBACK   (UTRAN_FDD_NeighbourCells_t, (void*) 14, NrOfCells, BitsInCellInfo), */
   M_VAR_BITMAP (UTRAN_FDD_NeighbourCells_t, CellInfo,  BitsInCellInfo, 0),
 CSN_DESCR_END  (UTRAN_FDD_NeighbourCells_t)
 
@@ -3804,16 +3921,104 @@ CSN_DESCR_BEGIN(UTRAN_FDD_Description_t)
   M_REC_TARRAY (UTRAN_FDD_Description_t, CellParams, UTRAN_FDD_NeighbourCells_t, NrOfFrequencies),
 CSN_DESCR_END  (UTRAN_FDD_Description_t)
 
+
+const static guint8 NR_OF_TDD_CELLS_map[32] = {0, 9, 17, 25, 32, 39, 46, 53, 59, 65, 71, 77, 83, 89, 95, 101, 106, 111, 116, 121, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+CSN_CallBackStatus_t callback_UTRAN_TDD_map_NrOfFrequencies(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{  /* TS 44.060 Table 11.2.9b.2.b */
+    guint8 * pNrOfCells = (guint8*)param1;
+    guint8 * pBitsInCellInfo = (guint8*)param2;
+
+    if( *pNrOfCells < 32 )
+    {
+        *pBitsInCellInfo = NR_OF_TDD_CELLS_map[*pNrOfCells];
+    }
+    else
+    {
+        *pBitsInCellInfo = 0;
+    }
+
+    return 0;
+}
+
+CSN_CallBackStatus_t callback_UTRAN_TDD_compute_TDD_CELL_INFORMATION(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    proto_item   *ti;
+    proto_tree   *subtree;
+    UTRAN_TDD_NeighbourCells_t * pUtranTddNcell = (UTRAN_TDD_NeighbourCells_t*)param1;
+    gint xdd_cell_info, wsize, nwi, jwi, w[64], i, iused;
+    gint curr_bit_offset, idx;
+
+    curr_bit_offset = bit_offset;
+    idx = pUtranTddNcell->BitsInCellInfo;
+
+    if( idx > 0 )
+    {
+        ti = proto_tree_add_text(tree, tvb, curr_bit_offset>>3, 1,  "TDD_CELL_INFORMATION: ");
+        subtree = proto_item_add_subtree(ti, ett_csn1);
+        
+        if (pUtranTddNcell->Indic0)
+        {
+            proto_tree_add_text(tree,tvb, curr_bit_offset>>3, 0, "Cell Parameter: %d", 0);
+            proto_tree_add_text(tree,tvb, curr_bit_offset>>3, 0, "Sync Case TSTD: %d", 0);
+            proto_tree_add_text(tree,tvb, curr_bit_offset>>3, 0, "Diversity TDD: %d", 0);
+        }
+
+        if (idx)
+        {
+            wsize = 10;
+            nwi = 1;
+            jwi = 0;
+            i = 1;
+
+            while (idx > 0)
+            {
+                w[i] = tvb_get_bits(tvb, curr_bit_offset, wsize, ENC_BIG_ENDIAN);
+                curr_bit_offset += wsize;
+                idx -= wsize;
+                if (w[i] == 0)
+                {
+                    idx = 0;
+                    break;
+                }
+                if (++jwi==nwi)
+                {
+                    jwi = 0;
+                    nwi <<= 1;
+                    wsize--;
+                }
+                i++;
+            }
+            if (idx < 0)
+            {
+                curr_bit_offset += idx;
+            }
+            iused = i-1;
+
+            for (i=1; i <= iused; i++)
+            {
+                xdd_cell_info = f_k(i, w, 1024);
+                proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, 0, "Cell Parameter: %d", xdd_cell_info & 0x007F);
+                proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, 0, "Sync Case TSTD: %d", (xdd_cell_info >> 7) & 0x01);
+                proto_tree_add_text(subtree,tvb, curr_bit_offset>>3, 0, "Diversity TDD: %d", (xdd_cell_info >> 8) & 0x01);
+            }
+        }
+    }
+
+    return curr_bit_offset - bit_offset;
+}
+
+
 static const
 CSN_DESCR_BEGIN(UTRAN_TDD_NeighbourCells_t)
   M_UINT       (UTRAN_TDD_NeighbourCells_t,  ZERO,      1, &hf_utran_tdd_neighbourcells_zero),
   M_UINT       (UTRAN_TDD_NeighbourCells_t,  UARFCN,   14, &hf_utran_tdd_neighbourcells_uarfcn),
   M_UINT       (UTRAN_TDD_NeighbourCells_t,  Indic0,      1, &hf_utran_tdd_neighbourcells_indic0),
   M_UINT       (UTRAN_TDD_NeighbourCells_t,  NrOfCells,   5, &hf_utran_tdd_neighbourcells_nrofcells),
-/*  M_CALLBACK   (UTRAN_TDD_NeighbourCells_t, (void*) 23, NrOfCells, BitsInCellInfo), */
-  M_VAR_BITMAP (UTRAN_TDD_NeighbourCells_t, CellInfo,  BitsInCellInfo, 0),
+  M_CALLBACK   (UTRAN_TDD_NeighbourCells_t, (void*)callback_UTRAN_TDD_map_NrOfFrequencies, NrOfCells, BitsInCellInfo),
+  M_CALLBACK   (UTRAN_TDD_NeighbourCells_t, (void*)callback_UTRAN_TDD_compute_TDD_CELL_INFORMATION, ZERO, CellInfo),
 CSN_DESCR_END  (UTRAN_TDD_NeighbourCells_t)
 
+
 static const
 CSN_DESCR_BEGIN(UTRAN_TDD_Description_t)
   M_NEXT_EXIST (UTRAN_TDD_Description_t, existBandwidth, 1),
@@ -3957,6 +4162,20 @@ CSN_DESCR_BEGIN(lu_ModeOnlyCellSelectionParamsWithFreqDiff_t)
   M_TYPE       (lu_ModeOnlyCellSelectionParamsWithFreqDiff_t, lu_ModeOnlyCellSelectionParams, lu_ModeOnlyCellSelection_t),
 CSN_DESCR_END  (lu_ModeOnlyCellSelectionParamsWithFreqDiff_t)
 
+CSN_CallBackStatus_t callback_init_luMode_Cell_Sel_Param_FREQUENCY_DIFF(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    guint  i;
+    guint8 freq_diff_len = *(guint8*)param1;
+    lu_ModeOnlyCellSelectionParamsWithFreqDiff_t *pArray = (lu_ModeOnlyCellSelectionParamsWithFreqDiff_t*)param2;
+
+    for( i=0; i<16; i++, pArray++ )
+    {
+        pArray->FREQ_DIFF_LENGTH = freq_diff_len;
+    }
+
+    return 0;
+}
+
 static const
 CSN_DESCR_BEGIN(Add_lu_ModeOnlyFrequencyList_t)
   M_UINT       (Add_lu_ModeOnlyFrequencyList_t,  START_FREQUENCY,  10, &hf_add_lu_modeonlyfrequencylist_start_frequency),
@@ -3968,6 +4187,8 @@ CSN_DESCR_BEGIN(Add_lu_ModeOnlyFrequencyList_t)
   M_UINT       (Add_lu_ModeOnlyFrequencyList_t,  NR_OF_FREQUENCIES,  5, &hf_add_lu_modeonlyfrequencylist_nr_of_frequencies),
   M_UINT       (Add_lu_ModeOnlyFrequencyList_t,  FREQ_DIFF_LENGTH,  3, &hf_add_lu_modeonlyfrequencylist_freq_diff_length),
 
+  M_CALLBACK   (Add_lu_ModeOnlyFrequencyList_t, (void*)callback_init_luMode_Cell_Sel_Param_FREQUENCY_DIFF, FREQ_DIFF_LENGTH, lu_ModeOnlyCellSelectionParamsWithFreqDiff),
+
   M_VAR_TARRAY (Add_lu_ModeOnlyFrequencyList_t, lu_ModeOnlyCellSelectionParamsWithFreqDiff, lu_ModeOnlyCellSelectionParamsWithFreqDiff_t, NR_OF_FREQUENCIES),
 CSN_DESCR_END  (Add_lu_ModeOnlyFrequencyList_t)
 
@@ -5532,13 +5753,23 @@ CSN_DESCR_END  (COMPACT_Cell_Sel_t)
 
 static const
 CSN_DESCR_BEGIN(COMPACT_Neighbour_Cell_Param_Remaining_t)
-  /* this FREQ_DIFF_LENGTH is not initialised, it should be the SAME as COMPACT_Neighbour_Cell_Param_t.FREQ_DIFF_LENGTH.
-  * So it is buggy, but there is no way to handle it. Same issue is in Cell_Selection_Params_With_FreqDiff_t.FREQ_DIFF_LENGTH.
-  */
   M_VAR_BITMAP (COMPACT_Neighbour_Cell_Param_Remaining_t,  FREQUENCY_DIFF, FREQ_DIFF_LENGTH, 0),
   M_TYPE       (COMPACT_Neighbour_Cell_Param_Remaining_t,  COMPACT_Cell_Sel_Remain_Cells, COMPACT_Cell_Sel_t),
 CSN_DESCR_END  (COMPACT_Neighbour_Cell_Param_Remaining_t)
 
+CSN_CallBackStatus_t callback_init_COMP_Ncell_Param_FREQUENCY_DIFF(proto_tree *tree, tvbuff_t *tvb, void* param1, void* param2, int bit_offset, int ett_csn1)
+{
+    guint  i;
+    guint8 freq_diff_len = *(guint8*)param1;
+    COMPACT_Neighbour_Cell_Param_Remaining_t *pCom_NCell_Param_rem = (COMPACT_Neighbour_Cell_Param_Remaining_t*)param2;
+
+    for( i=0; i<16; i++, pCom_NCell_Param_rem++ )
+    {
+        pCom_NCell_Param_rem->FREQ_DIFF_LENGTH = freq_diff_len;
+    }
+
+    return 0;
+}
 
 static const
 CSN_DESCR_BEGIN(COMPACT_Neighbour_Cell_Param_t)
@@ -5546,6 +5777,7 @@ CSN_DESCR_BEGIN(COMPACT_Neighbour_Cell_Param_t)
   M_TYPE       (COMPACT_Neighbour_Cell_Param_t,  COMPACT_Cell_Sel, COMPACT_Cell_Sel_t),
   M_UINT       (COMPACT_Neighbour_Cell_Param_t,  NR_OF_REMAINING_CELLS, 4, &hf_packet_compact_ncell_param_nr_of_remaining_cells),
   M_UINT_OFFSET(COMPACT_Neighbour_Cell_Param_t,  FREQ_DIFF_LENGTH, 3, 1),
+  M_CALLBACK   (COMPACT_Neighbour_Cell_Param_t, (void*)callback_init_COMP_Ncell_Param_FREQUENCY_DIFF, FREQ_DIFF_LENGTH, COMPACT_Neighbour_Cell_Param_Remaining),
   M_VAR_TARRAY (COMPACT_Neighbour_Cell_Param_t,  COMPACT_Neighbour_Cell_Param_Remaining, COMPACT_Neighbour_Cell_Param_Remaining_t, NR_OF_REMAINING_CELLS),
 CSN_DESCR_END  (COMPACT_Neighbour_Cell_Param_t)
 
index e92d324..2df95db 100644 (file)
@@ -5086,4 +5086,7 @@ typedef struct
 
 } EnhancedMeasurementReport_t;
 
+extern gint f_k(gint k, gint *w, gint range);
+
+
 #endif /* __PACKET_GSM_RLCMAC_H__ */