aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2009-05-15 18:38:13 +0000
committerAnders Broman <anders.broman@ericsson.com>2009-05-15 18:38:13 +0000
commit1464f7ca84792e42dbaeb57f66efb40783d9fea7 (patch)
tree3e97b6d2a0fa0012581c37903f754b47aaf3503c
parent54cfb391431ab5f4bc02bf8265b3ac9e393226b8 (diff)
Introduce decode_bits_in_field() and use it.
clean up some left owers from previous checkin. svn path=/trunk/; revision=28373
-rw-r--r--epan/dissectors/packet-gsm_a_gm.c49
-rw-r--r--epan/to_str.c53
-rw-r--r--epan/to_str.h2
3 files changed, 84 insertions, 20 deletions
diff --git a/epan/dissectors/packet-gsm_a_gm.c b/epan/dissectors/packet-gsm_a_gm.c
index ee3730f0ff..9cc8756030 100644
--- a/epan/dissectors/packet-gsm_a_gm.c
+++ b/epan/dissectors/packet-gsm_a_gm.c
@@ -1079,6 +1079,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
guint add_ocetets; /* octets which are covered by one element -1 */
guint curr_bits_length;
guchar acc_type;
+ guint value;
const gchar *str;
gchar multi_slot_str[64][230] = {
"Not specified", /* 00 */
@@ -1158,6 +1159,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
bits_in_oct = 0;
oct = 0;
+
do
{
/* check for a new round */
@@ -1208,10 +1210,6 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
acc_type = oct>>(32-bits_needed);
- proto_tree_add_text(tf_tree,
- tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "Access Technology Type: (%u) %s",acc_type,val_to_str(acc_type, gsm_a_gm_acc_tech_type_vals, "Unknown"));
-
proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_tech_type, tvb, bit_offset, 4, FALSE);
bit_offset+=4;
@@ -1227,9 +1225,6 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
GET_DATA;
bits_length = curr_bits_length = oct>>(32-bits_needed);
- proto_tree_add_text(tf_tree,
- tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "Length: 0x%02x bits (%u)",bits_length,bits_length);
proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_cap_struct_len, tvb, bit_offset, 7, FALSE);
proto_item_set_len(tf, (bits_length>>3)+1);
/* This is already done - length doesn't contain this field
@@ -1298,9 +1293,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
acc_type = oct>>(32-bits_needed);
- proto_tree_add_text(tf_tree,
- tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "Access Technology Type: (%u) %s",acc_type,val_to_str(acc_type, gsm_a_gm_acc_tech_type_vals, "Unknown"));
+ proto_tree_add_bits_item(tf_tree, hf_gsm_a_gm_acc_cap_struct_len, tvb, bit_offset, 7, FALSE);
bit_offset+=4;
curr_bits_length -= bits_needed;
@@ -1313,10 +1306,11 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
bits_needed = 3;
GET_DATA;
+ value = tvb_get_bits8(tvb, bit_offset, 3);
/* analyse bits */
if ( acc_type == 0x04 ) /* GSM 1900 */
{
- switch ( oct>>(32-bits_needed) )
+ switch ( value )
{
case 0x01: str="1 W (30 dBm)"; break;
case 0x02: str="0,25 W (24 dBm)"; break;
@@ -1326,7 +1320,10 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
}
else if ( acc_type == 0x03 )
{
- switch ( oct>>(32-bits_needed) )
+ /*
+ * 3 GSM 1800
+ */
+ switch ( value )
{
case 0x01: str="1 W (30 dBm)"; break;
case 0x02: str="0,25 W (24 dBm)"; break;
@@ -1336,7 +1333,15 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
}
else if ( acc_type <= 0x08 )
{
- switch ( oct>>(32-bits_needed) )
+ /* 0 GSM P
+ * 1 GSM E
+ * 2 GSM R
+ * 5 GSM 450
+ * 6 GSM 480
+ * 7 GSM 850
+ */
+
+ switch ( value )
{
case 0x02: str="8 W (39 dBm)"; break;
case 0x03: str="5 W (37 dBm)"; break;
@@ -1348,9 +1353,10 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
else
str="Not specified??";
+ /* decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value)*/
proto_tree_add_text(tf_tree,
tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "RF Power Capability, GMSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
+ "%s RF Power Capability, GMSK Power Class: (%u) %s", decode_bits_in_field(bit_offset, 3, value), value, str);
bit_offset+=3;
curr_bits_length -= bits_needed;
oct <<= bits_needed;
@@ -1362,8 +1368,9 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
bits_needed = 2;
GET_DATA;
+ value = tvb_get_bits8(tvb, bit_offset, 2);
/* analyse bits */
- switch ( oct>>(32-bits_needed) )
+ switch ( value )
{
case 0x00: str="8PSK modulation not supported for uplink"; break;
case 0x01: str="Power class E1"; break;
@@ -1374,7 +1381,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
proto_tree_add_text(tf_tree,
tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "8PSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
+ "8PSK Power Class: (%u) %s",value,str);
bit_offset+=2;
curr_bits_length -= bits_needed;
oct <<= bits_needed;
@@ -1391,10 +1398,11 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
bits_needed = 3;
GET_DATA;
+ value = tvb_get_bits8(tvb, bit_offset, 3);
/* analyse bits */
if ( acc_type == 0x04 ) /* GSM 1900 */
{
- switch ( oct>>(32-bits_needed) )
+ switch ( value )
{
case 0x01: str="1 W (30 dBm)"; break;
case 0x02: str="0,25 W (24 dBm)"; break;
@@ -1404,7 +1412,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
}
else if ( acc_type == 0x03 )
{
- switch ( oct>>(32-bits_needed) )
+ switch ( value )
{
case 0x01: str="1 W (30 dBm)"; break;
case 0x02: str="0,25 W (24 dBm)"; break;
@@ -1414,7 +1422,7 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
}
else if ( acc_type <= 0x08 )
{
- switch ( oct>>(32-bits_needed) )
+ switch ( value )
{
case 0x02: str="8 W (39 dBm)"; break;
case 0x03: str="5 W (37 dBm)"; break;
@@ -1428,7 +1436,8 @@ de_gmm_ms_radio_acc_cap(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint l
proto_tree_add_text(tf_tree,
tvb, curr_offset-1-add_ocetets, 1+add_ocetets,
- "RF Power Capability, GMSK Power Class: (%u) %s",oct>>(32-bits_needed),str);
+ "%s RF Power Capability, GMSK Power Class: (%u) %s", decode_bits_in_field(bit_offset, 3, value), value,str);
+
bit_offset+=3;
curr_bits_length -= bits_needed;
oct <<= bits_needed;
diff --git a/epan/to_str.c b/epan/to_str.c
index 1cb44687e6..37b6f3c49b 100644
--- a/epan/to_str.c
+++ b/epan/to_str.c
@@ -741,6 +741,59 @@ fcwwn_to_str (const guint8 *ad)
}
return (ethstr);
}
+/*
+ * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
+ * with the length in bits of no_of_bits based on value.
+ * Ex: ..xx x...
+ */
+
+char *
+decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value)
+{
+ guint64 mask = 0,tmp;
+ char *str;
+ int bit;
+ int i;
+
+ mask = 1;
+ mask = mask << (no_of_bits-1);
+
+ /* prepare the string */
+ str=ep_alloc(256);
+ str[0]='\0';
+ for(bit=0;bit<((int)(bit_offset&0x07));bit++){
+ if(bit&&(!(bit%4))){
+ strcat(str, " ");
+ }
+ strcat(str,".");
+ }
+
+ /* read the bits for the int */
+ for(i=0;i<no_of_bits;i++){
+ if(bit&&(!(bit%4))){
+ strcat(str, " ");
+ }
+ if(bit&&(!(bit%8))){
+ strcat(str, " ");
+ }
+ bit++;
+ tmp = value & mask;
+ if(tmp != 0){
+ strcat(str, "1");
+ } else {
+ strcat(str, "0");
+ }
+ mask = mask>>1;
+ }
+
+ for(;bit%8;bit++){
+ if(bit&&(!(bit%4))){
+ strcat(str, " ");
+ }
+ strcat(str,".");
+ }
+ return str;
+}
/* Generate, into "buf", a string showing the bits of a bitfield.
Return a pointer to the character after that string. */
diff --git a/epan/to_str.h b/epan/to_str.h
index 48d1e3d2f4..6bf5a6cfc1 100644
--- a/epan/to_str.h
+++ b/epan/to_str.h
@@ -82,6 +82,8 @@ extern gchar* guid_to_str_buf(const e_guid_t*, gchar*, int);
void tipc_addr_to_str_buf( const guint8 *data, gchar *buf, int buf_len);
+extern char *decode_bits_in_field(gint bit_offset, gint no_of_bits, guint64 value);
+
extern char *other_decode_bitfield_value(char *buf, guint32 val, guint32 mask,
int width);
extern char *decode_bitfield_value(char *buf, guint32 val, guint32 mask,