# HG changeset patch # User Luke Mewburn # Date 1582068020 -39600 # Node ID 67c263056d78fc5ccf755e053d92ed86a0dca451 # Parent b1e8c5281d295292d6e530013a58a6315aa00920 fd_msg_search_avp: search msg_or_avp, not just msg Change fd_msg_search_avp() to support searching struct msg or struct avp, and not just struct msg. diff -r b1e8c5281d29 -r 67c263056d78 include/freeDiameter/libfdproto.h --- a/include/freeDiameter/libfdproto.h Wed Feb 19 10:07:17 2020 +1100 +++ b/include/freeDiameter/libfdproto.h Wed Feb 19 10:20:20 2020 +1100 @@ -2366,12 +2366,12 @@ * FUNCTION: fd_msg_search_avp * * PARAMETERS: - * msg : The message structure in which to search the AVP. + * reference : Pointer to a valid msg or avp in which to search the AVP. * what : The dictionary model of the AVP to search. * avp : location where the AVP reference is stored if found. * * DESCRIPTION: - * Search the first top-level AVP of a given model inside a message. + * Search for the first top-level AVP of a given model inside a message or AVP. * Note: only the first instance of the AVP is returned by this function. * Note: only top-level AVPs are searched, not inside grouped AVPs. * Use msg_browse if you need more advanced search features. @@ -2381,7 +2381,7 @@ * EINVAL : A parameter is invalid. * ENOENT : No AVP has been found, and "avp" was NULL (otherwise, *avp is set to NULL and 0 returned). */ -int fd_msg_search_avp ( struct msg * msg, struct dict_object * what, struct avp ** avp ); +int fd_msg_search_avp ( msg_or_avp * reference, struct dict_object * what, struct avp ** avp ); /* * FUNCTION: fd_msg_free diff -r b1e8c5281d29 -r 67c263056d78 libfdproto/messages.c --- a/libfdproto/messages.c Wed Feb 19 10:07:17 2020 +1100 +++ b/libfdproto/messages.c Wed Feb 19 10:20:20 2020 +1100 @@ -596,29 +596,29 @@ return 0; } -/* Search a given AVP model in a message */ -int fd_msg_search_avp ( struct msg * msg, struct dict_object * what, struct avp ** avp ) +/* Search a given AVP model in a message or AVP */ +int fd_msg_search_avp ( msg_or_avp * reference, struct dict_object * what, struct avp ** avp ) { struct avp * nextavp; struct dict_avp_data dictdata; enum dict_object_type dicttype; - TRACE_ENTRY("%p %p %p", msg, what, avp); + TRACE_ENTRY("%p %p %p", reference, what, avp); - CHECK_PARAMS( CHECK_MSG(msg) && what ); + CHECK_PARAMS( VALIDATE_OBJ(reference) && what ); CHECK_PARAMS( (fd_dict_gettype(what, &dicttype) == 0) && (dicttype == DICT_AVP) ); CHECK_FCT( fd_dict_getval(what, &dictdata) ); - /* Loop on all top AVPs */ - CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); + /* Loop on all top AVPs in message or AVP */ + CHECK_FCT( fd_msg_browse(reference, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); while (nextavp) { if ( (nextavp->avp_public.avp_code == dictdata.avp_code) && (nextavp->avp_public.avp_vendor == dictdata.avp_vendor) ) /* always 0 if no V flag */ break; - /* Otherwise move to next AVP in the message */ + /* Otherwise move to next AVP in the message or AVP */ CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); } diff -r b1e8c5281d29 -r 67c263056d78 tests/testmesg.c --- a/tests/testmesg.c Wed Feb 19 10:07:17 2020 +1100 +++ b/tests/testmesg.c Wed Feb 19 10:20:20 2020 +1100 @@ -680,6 +680,7 @@ { struct dict_object * avp_model; struct avp * found; + struct avp * grouped = NULL; struct avp_hdr * avpdata = NULL; /* Now find the ACR dictionary object */ @@ -687,14 +688,41 @@ CPYBUF(); CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) ); - + CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) ); +#if 0 + LOG_D("msg: %s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, msg, fd_g_config->cnf_dict, 0, 1)); +#endif + /* Search this AVP instance in the msg */ CHECK( 0, fd_msg_search_avp( msg, avp_model, &found ) ); /* Check the AVP value is 3.1415 */ CHECK( 0, fd_msg_avp_hdr ( found, &avpdata ) ); CHECK( 3.1415F, avpdata->avp_value->f32 ); - + + /* Search for the first grouped message */ + { + struct dict_avp_request grouped_req = { 73565, 0, "AVP Test - grouped"}; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &grouped_req, &avp_model, ENOENT ) ); + } + CHECK( 0, fd_msg_search_avp( msg, avp_model, &grouped ) ); +#if 0 + LOG_D("grouped: %s", fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, grouped, fd_g_config->cnf_dict, 0, 1)); +#endif + + /* Find the first item in the grouped */ + { + struct dict_avp_request avp_req = { 73565, 0, "AVP Test - os"}; + CHECK( 0, fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_req, &avp_model, ENOENT ) ); + } + + CHECK( 0, fd_msg_search_avp( grouped, avp_model, &found ) ); + + /* Check the AVP value is "1" */ + CHECK( 0, fd_msg_avp_hdr ( found, &avpdata ) ); + CHECK( 8, avpdata->avp_value->os.len ); + CHECK( 0, memcmp(avpdata->avp_value->os.data, "12345678", 8)); + /* reinit the msg */ CHECK( 0, fd_msg_free ( msg ) );