changeset 339:2b62cd08cf02

Fixed parsing of float32 and float64 AVP values, and added regression test
author Sebastien Decugis <sdecugis@nict.go.jp>
date Wed, 01 Apr 2009 16:32:10 +0900
parents be43a4344cf9
children 744a4d868388
files waaad/message.c waaad/tests/testmesg.c
diffstat 2 files changed, 263 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/waaad/message.c	Wed Apr 01 11:17:11 2009 +0900
+++ b/waaad/message.c	Wed Apr 01 16:32:10 2009 +0900
@@ -1032,21 +1032,15 @@
 			break;
 	
 		case AVP_TYPE_UNSIGNED32:
+		case AVP_TYPE_FLOAT32: /* For float, we must not cast, or the value is changed. Instead we use implicit cast by changing the member of the union */
 			avp->avp_storage.u32 = (uint32_t)ntohl(*(uint32_t *)avp->avp_source);
 			break;
 	
 		case AVP_TYPE_UNSIGNED64:
+		case AVP_TYPE_FLOAT64: /* same as 32 bits */
 			avp->avp_storage.u64 = (uint64_t)ntohll(*(uint64_t *)avp->avp_source);
 			break;
 	
-		case AVP_TYPE_FLOAT32:
-			avp->avp_storage.f32 = (float)ntohl(*(uint32_t *)avp->avp_source);
-			break;
-	
-		case AVP_TYPE_FLOAT64:
-			avp->avp_storage.f64 = (double)ntohll(*(uint64_t *)avp->avp_source);
-			break;
-	
 	}
 	
 	/* The value is now set, so set the data pointer and return 0 */
--- a/waaad/tests/testmesg.c	Wed Apr 01 11:17:11 2009 +0900
+++ b/waaad/tests/testmesg.c	Wed Apr 01 16:32:10 2009 +0900
@@ -615,8 +615,8 @@
 			CHECK( 0x00, buf[26] );
 			CHECK( 0x0C, buf[27] );
 			CHECK( 0x40, buf[28] ); /* Value: 3.1415:  sign = '+' => most significant bit = 0 */
-			CHECK( 0x49, buf[29] ); /* 2 <= 3.1415 < 4 => exponent = 2 => biaised (on 8 bits) = (decimal) 129 = (binary) 100 0000 0 */
-			CHECK( 0x0e, buf[30] ); /* significand = (decimal) 0.57075 = (binary) 0.100 1001 0000 1110 0101 0110 */
+			CHECK( 0x49, buf[29] ); /* 2 <= 3.1415 < 4 => exponent = 1 => biaised (on 8 bits) = (decimal) 128 = (binary) 100 0000 0 */
+			CHECK( 0x0e, buf[30] ); /* significand = (decimal) 1.57075 = (binary) 1.100 1001 0000 1110 0101 0110 */
 			CHECK( 0x56, buf[31] ); /* total => 0100 0000 0100 1001 0000 1110 0101 0110 = (hexa) 40 49 0e 56*/
 			
 			/* The other AVPs will be tested by successful parsing... */
@@ -963,6 +963,265 @@
 		/* Ok, it's done */
 		CHECK( 0, msg_free( cer, 1 ) );
 	}
+	
+	/* Check proper encoding / decoding for all basic types of AVP */
+	{
+		{
+			dict_avp_data_t avp_data = { 91001, 0, "AVP Test 2 - os", 0, 0, AVP_TYPE_OCTETSTRING };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91002, 0, "AVP Test 2 - i32", 0, 0, AVP_TYPE_INTEGER32 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91003, 0, "AVP Test 2 - i64", 0, 0, AVP_TYPE_INTEGER64 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91004, 0, "AVP Test 2 - u32", 0, 0, AVP_TYPE_UNSIGNED32 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91005, 0, "AVP Test 2 - u64", 0, 0, AVP_TYPE_UNSIGNED64 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91006, 0, "AVP Test 2 - f32", 0, 0, AVP_TYPE_FLOAT32 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		{
+			dict_avp_data_t avp_data = { 91007, 0, "AVP Test 2 - f64", 0, 0, AVP_TYPE_FLOAT64 };
+			CHECK( 0, dict_new ( DICT_AVP, &avp_data , NULL, NULL ) );
+		}
+		
+		{
+			dict_object_t * cmd_model = NULL;
+			msg_t         * msg = NULL;
+			dict_object_t * avp_model = NULL;
+			msg_avp_t     * avp = NULL;
+			avp_value_t	value;
+			msg_avp_t * avpi = NULL;
+			msg_avp_t * avpch = NULL;
+			msg_avp_data_t * avpdata = NULL;
+			msg_data_t * msgdata = NULL;
+
+			CHECK( 0, dict_search ( DICT_COMMAND, CMD_BY_NAME, "Test-Command-Request", &cmd_model ) );
+
+			/* Create a message */
+			CHECK( 0, msg_new ( cmd_model, 0, &msg ) );
+			CHECK( 0, msg_data ( msg, &msgdata ) );
+			
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0, 	"AVP Test 2 - os" );
+			value.os.data = (unsigned char *) "waaad";
+			value.os.len = 6;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - i32" );
+			value.i32 = 0x123456;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - i32" );
+			value.i32 = -0x123456;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - i64" );
+			value.i64 = 0x11223344556677LL;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - i64" );
+			value.i64 = -0x11223344556677LL;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - u32" );
+			value.u32 = 0xFEDCBA98;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - u64" );
+			value.u64 = 0x123456789abcdef0LL;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - f32" );
+			value.f32 = 2097153.0F;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+
+			ADD_AVP( msg, MSG_BRW_LAST_CHILD, avpi, 0,	"AVP Test 2 - f64" );
+			value.f64 = -1099511627777LL;
+			CHECK( 0, msg_avp_setvalue ( avpi, &value ) );
+			
+			/* Ok now bufferize */
+			CHECK( 0, msg_update_length ( msg ) );
+			
+			CHECK( 0, msg_bufferize( msg, &buf, NULL ) );
+			
+			/* Test the first bytes */
+			CHECK( 0x01, buf[0] ); /* Version */
+			CHECK( 0x00, buf[1] ); /* Length: 148 = 0x000094 */
+			CHECK( 0x00, buf[2] );
+			CHECK( 0x94, buf[3] );
+			CHECK( 0x80, buf[4] ); /* flags: only "R" is set. */
+			CHECK( 0x01, buf[5] ); /* Command code: 73573 = 0x011F65 */
+			CHECK( 0x1F, buf[6] );
+			CHECK( 0x65, buf[7] );
+			CHECK( 0x00, buf[8] ); /* App ID */
+			CHECK( 0x01, buf[9] ); 
+			CHECK( 0x1F, buf[10] );
+			CHECK( 0x5E, buf[11] );
+			CHECK( 0x00, buf[12] ); /* hop-by-hop id */
+			CHECK( 0x00, buf[13] );
+			CHECK( 0x00, buf[14] );
+			CHECK( 0x00, buf[15] );
+			CHECK( 0x00, buf[16] ); /* end-to-end id */
+			CHECK( 0x00, buf[17] );
+			CHECK( 0x00, buf[18] );
+			CHECK( 0x00, buf[19] );
+			
+			CHECK( 0x00, buf[20] ); /* First AVP (AVP Test 2 - os) begin: code 91001 = 0x00016379 */
+			CHECK( 0x01, buf[21] );
+			CHECK( 0x63, buf[22] );
+			CHECK( 0x79, buf[23] );
+			CHECK( 0x00, buf[24] ); /* flags: 0 */
+			CHECK( 0x00, buf[25] ); /* length: 14 = 0x00000e */
+			CHECK( 0x00, buf[26] );
+			CHECK( 0x0e, buf[27] );
+			
+			CHECK( 0x77, buf[28] ); /* "waaad\0" + padding */
+			CHECK( 0x61, buf[29] );
+			CHECK( 0x61, buf[30] );
+			CHECK( 0x61, buf[31] );
+			CHECK( 0x64, buf[32] );
+			CHECK( 0x00, buf[33] );
+			CHECK( 0x00, buf[34] );
+			CHECK( 0x00, buf[35] );
+			
+			/* 36 ~ 43 : 2nd AVP header (size at last octet) */
+			CHECK( 0x0c, buf[43] );
+			CHECK( 0x00, buf[44] ); /* 0x123456 stored in integer32 in network byte order */
+			CHECK( 0x12, buf[45] );
+			CHECK( 0x34, buf[46] );
+			CHECK( 0x56, buf[47] );
+			
+			/* 48 ~ 55 : next AVP header */
+			CHECK( 0xff, buf[56] ); /* -0x123456 stored in integer32 in network byte order. */ 
+			CHECK( 0xed, buf[57] ); /* We assume that two's complement is the correct representation, although it's not clearly specified. */
+			CHECK( 0xcb, buf[58] ); /* 00 12 34 56 inversed => FF ED CB A9 */
+			CHECK( 0xaa, buf[59] ); /* then "+1" => FF ED CB AA */
+			
+			/* 60 ~ 67 : next header */
+			CHECK( 0x10, buf[67] ); /* (the size) */
+			CHECK( 0x00, buf[68] ); /* 0x11223344556677 in network byte order */
+			CHECK( 0x11, buf[69] );
+			CHECK( 0x22, buf[70] );
+			CHECK( 0x33, buf[71] );
+			CHECK( 0x44, buf[72] );
+			CHECK( 0x55, buf[73] );
+			CHECK( 0x66, buf[74] );
+			CHECK( 0x77, buf[75] );
+			
+			/* 76 ~ 83 : next header */
+			CHECK( 0xFF, buf[84] ); /*  - 0x11223344556677 (in two's complement) */
+			CHECK( 0xEE, buf[85] ); /* gives FF EE DD CC BB AA 99 89 */
+			CHECK( 0xDD, buf[86] );
+			CHECK( 0xCC, buf[87] );
+			CHECK( 0xBB, buf[88] );
+			CHECK( 0xAA, buf[89] );
+			CHECK( 0x99, buf[90] );
+			CHECK( 0x89, buf[91] );
+			
+			/* 92 ~ 99 : next header */
+			CHECK( 0x0c, buf[99] ); /* (the size) */
+			CHECK( 0xFE, buf[100]); /* 0xFEDCBA98 in network byte order */
+			CHECK( 0xDC, buf[101]);
+			CHECK( 0xBA, buf[102]);
+			CHECK( 0x98, buf[103]);
+			
+			/* 104 ~ 111 : next header */
+			CHECK( 0x10, buf[111] ); /* (the size) */
+			CHECK( 0x12, buf[112]); /* 0x123456789abcdef0LL in network byte order */
+			CHECK( 0x34, buf[113]);
+			CHECK( 0x56, buf[114]);
+			CHECK( 0x78, buf[115]);
+			CHECK( 0x9a, buf[116]);
+			CHECK( 0xbc, buf[117]);
+			CHECK( 0xde, buf[118]);
+			CHECK( 0xf0, buf[119]);
+			
+			/* 120 ~ 127 : next header */
+			CHECK( 0x0c, buf[127] ); /* (the size) */
+			CHECK( 0x4a, buf[128]); /* http://en.wikipedia.org/wiki/IEEE_754-1985 to get descvription of the format */
+			CHECK( 0x00, buf[129]); /* v = 2097153 = 2^21 + 2 ^ 0; sign : "+", 2^21 <= v < 2^22 => exponent = 21; biaised on 8 bits => 21 + 127 => 100 1010 0 */
+			CHECK( 0x00, buf[130]); /* v = (+1) * (1 ^ 21) * ( 1 + 2^-21 ) => significand 000 0000 0000 0000 0000 0100 */
+			CHECK( 0x04, buf[131]); /* result: 4a 00 00 04 */
+			
+			/* 132 ~ 139 : next header */
+			CHECK( 0x10, buf[139] ); /* (the size) */
+			CHECK( 0xc2, buf[140]); /* -1099511627777L ( 2^40 + 1 ) in network byte order */
+			CHECK( 0x70, buf[141]); /* sign: - => most significant bit = 1 */
+			CHECK( 0x00, buf[142]); /* 2^40 <= v < 2^41 => biaised exponent on 11 bits: 1023 + 40: 100 0010  0111 */
+			CHECK( 0x00, buf[143]); /* significand: 1 + 2^-40 => 0000  0000 0000  0000 0000  0000 0000  0000 0000  0001 0000  0000 0000 */
+			CHECK( 0x00, buf[144]); /* result: c2 70 00 00 00 00 10 00 */
+			CHECK( 0x00, buf[145]);
+			CHECK( 0x10, buf[146]);
+			CHECK( 0x00, buf[147]);
+			
+			
+			
+			/* Okay, now delete the message and parse the buffer, then check we obtain the same values back */
+			#if 0
+			msg_dump_walk(0, msg);
+			#endif
+			CHECK( 0, msg_free( msg, 1 ) );
+			
+			CHECK( 0, msg_parse_buffer( &buf, 148, &msg) );
+			CHECK( 0, msg_parse_dict( msg ) );
+			#if 0
+			msg_dump_walk(0, msg);
+			#endif
+			
+			CHECK( 0, msg_browse ( msg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 6, avpdata->avp_data->os.len );
+			CHECK( 'w', (char)(avpdata->avp_data->os.data[0]) );
+			CHECK( 'a', (char)(avpdata->avp_data->os.data[1]) );
+			CHECK( 'd', (char)(avpdata->avp_data->os.data[4]) );
+			CHECK( '\0', (char)(avpdata->avp_data->os.data[5]) );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 0x123456, avpdata->avp_data->i32 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( -0x123456, avpdata->avp_data->i32 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 0x11223344556677LL, avpdata->avp_data->i64 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( -0x11223344556677LL, avpdata->avp_data->i64 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 0xFEDCBA98, avpdata->avp_data->u32 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 0x123456789abcdef0LL, avpdata->avp_data->u64 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( 2097153.0F, avpdata->avp_data->f32 );
+			
+			CHECK( 0, msg_browse ( avp, MSG_BRW_NEXT, &avp, NULL) );
+			CHECK( 0, msg_avp_data ( avp, &avpdata ) );
+			CHECK( -1099511627777LL, avpdata->avp_data->f64 );
+			
+			CHECK( 0, msg_free( msg, 1 ) );
+		}
+	}
+	
 
 	/* That's all for the tests yet */
 	PASSTEST();
"Welcome to our mercurial repository"