Mercurial > hg > waaad
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();