From dea5452b95dfaf18e38670a8e2b3b38f9175fdfd Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Thu, 23 Feb 2012 08:57:40 +0000 Subject: From Lei Chen: 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 svn path=/trunk/; revision=41149 --- epan/dissectors/packet-csn1.c | 9 +- epan/dissectors/packet-csn1.h | 2 + epan/dissectors/packet-gsm_a_rr.c | 2 +- epan/dissectors/packet-gsm_rlcmac.c | 244 +++++++++++++++++++++++++++++++++++- epan/dissectors/packet-gsm_rlcmac.h | 3 + 5 files changed, 252 insertions(+), 8 deletions(-) diff --git a/epan/dissectors/packet-csn1.c b/epan/dissectors/packet-csn1.c index 8d8f685e3c..87209e8117 100644 --- a/epan/dissectors/packet-csn1.c +++ b/epan/dissectors/packet-csn1.c @@ -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; } diff --git a/epan/dissectors/packet-csn1.h b/epan/dissectors/packet-csn1.h index 672f162750..8a5d8a1b54 100644 --- a/epan/dissectors/packet-csn1.h +++ b/epan/dissectors/packet-csn1.h @@ -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 { diff --git a/epan/dissectors/packet-gsm_a_rr.c b/epan/dissectors/packet-gsm_a_rr.c index 4b0040063b..1f77a15b92 100644 --- a/epan/dissectors/packet-gsm_a_rr.c +++ b/epan/dissectors/packet-gsm_a_rr.c @@ -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; diff --git a/epan/dissectors/packet-gsm_rlcmac.c b/epan/dissectors/packet-gsm_rlcmac.c index 079fe0e6e5..13b8ef9842 100644 --- a/epan/dissectors/packet-gsm_rlcmac.c +++ b/epan/dissectors/packet-gsm_rlcmac.c @@ -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) diff --git a/epan/dissectors/packet-gsm_rlcmac.h b/epan/dissectors/packet-gsm_rlcmac.h index e92d3240ef..2df95db973 100644 --- a/epan/dissectors/packet-gsm_rlcmac.h +++ b/epan/dissectors/packet-gsm_rlcmac.h @@ -5086,4 +5086,7 @@ typedef struct } EnhancedMeasurementReport_t; +extern gint f_k(gint k, gint *w, gint range); + + #endif /* __PACKET_GSM_RLCMAC_H__ */ -- cgit v1.2.3