# HG changeset patch # User Sebastien Decugis # Date 1355516674 -3600 # Node ID 4382d7420e65eea74ad53fa9ded16cec337013c4 # Parent 42d0a08cffa858b92e0572d22f92ccd1b107dd49 Add new AVP_BY_STRUCT method for searching vendor-specific AVPs. This allows more flexibility and superseeds AVP_BY_NAME_AND_VENDOR and AVP_BY_CODE_AND_VENDOR. diff -r 42d0a08cffa8 -r 4382d7420e65 include/freeDiameter/libfdproto.h --- a/include/freeDiameter/libfdproto.h Fri Dec 14 20:42:28 2012 +0100 +++ b/include/freeDiameter/libfdproto.h Fri Dec 14 21:24:34 2012 +0100 @@ -1330,12 +1330,30 @@ enum { AVP_BY_CODE = 50, /* "what" points to an avp_code_t, vendor is always 0 */ AVP_BY_NAME, /* "what" points to a char *, vendor is always 0 */ + AVP_BY_NAME_ALL_VENDORS,/* "what" points to a string. Might be quite slow... */ + AVP_BY_STRUCT, /* "what" points to a struct dict_avp_request_ex (see bellow) */ + + /* kept for backward compatibility, better use AVP_BY_STRUCT above instead */ AVP_BY_CODE_AND_VENDOR, /* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_code are set */ - AVP_BY_NAME_AND_VENDOR, /* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_name are set */ - AVP_BY_NAME_ALL_VENDORS /* "what" points to a string. Might be quite slow... */ + AVP_BY_NAME_AND_VENDOR /* "what" points to a struct dict_avp_request (see bellow), where avp_vendor and avp_name are set */ }; /* Struct used for some researchs */ +struct dict_avp_request_ex { + struct { + /* Only one of the following fields must be set. */ + struct dict_object * vendor; /* most efficient if already known, set to NULL to ignore */ + vendor_id_t vendor_id; /* set to 0 to ignore -- prefer AVP_BY_CODE or AVP_BY_NAME for vendor 0 */ + char * vendor_name; /* set to NULL to ignore */ + } avp_vendor; + + struct { + /* Only one of the following fields must be set */ + avp_code_t avp_code; /* set to 0 to ignore */ + char * avp_name; /* set to NULL to ignore */ + } avp_data; +}; + struct dict_avp_request { vendor_id_t avp_vendor; avp_code_t avp_code; @@ -1343,6 +1361,7 @@ }; + /*** * API usage : diff -r 42d0a08cffa8 -r 4382d7420e65 libfdproto/dictionary.c --- a/libfdproto/dictionary.c Fri Dec 14 20:42:28 2012 +0100 +++ b/libfdproto/dictionary.c Fri Dec 14 21:24:34 2012 +0100 @@ -976,6 +976,43 @@ } break; + case AVP_BY_STRUCT: + { + struct dict_avp_request_ex * _what = (struct dict_avp_request_ex *) what; + struct dict_object * vendor = NULL; + + CHECK_PARAMS( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name ); + CHECK_PARAMS( _what->avp_data.avp_code || _what->avp_data.avp_name ); + + /* Now look for the vendor first */ + if (_what->avp_vendor.vendor) { + CHECK_PARAMS( ! _what->avp_vendor.vendor_id && ! _what->avp_vendor.vendor_name ); + vendor = _what->avp_vendor.vendor; + } else if (_what->avp_vendor.vendor_id) { + CHECK_PARAMS( ! _what->avp_vendor.vendor_name ); + CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor.vendor_id, &vendor ) ); + } else { + CHECK_FCT( search_vendor( dict, VENDOR_BY_NAME, &_what->avp_vendor.vendor_name, &vendor ) ); + } + + if (vendor == NULL) { + if (result) + *result = NULL; + else + ret = ENOENT; + goto end; + } + + /* We now have our vendor = head of the appropriate avp list */ + if (_what->avp_data.avp_code) { + CHECK_PARAMS( ! _what->avp_data.avp_name ); + SEARCH_scalar( _what->avp_data.avp_code, &vendor->list[1], avp.avp_code, 1, (struct dict_object *)NULL ); + } else { + SEARCH_os0( _what->avp_data.avp_name, &vendor->list[2], avp.avp_name, 1); + } + } + break; + case AVP_BY_NAME_ALL_VENDORS: { struct fd_list * li; diff -r 42d0a08cffa8 -r 4382d7420e65 libfdproto/messages.c --- a/libfdproto/messages.c Fri Dec 14 20:42:28 2012 +0100 +++ b/libfdproto/messages.c Fri Dec 14 21:24:34 2012 +0100 @@ -1790,10 +1790,11 @@ /* Now try and resolve the model from the avp code and vendor */ if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { - struct dict_avp_request avpreq; - avpreq.avp_vendor = avp->avp_public.avp_vendor; - avpreq.avp_code = avp->avp_public.avp_code; - CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE_AND_VENDOR, &avpreq, &avp->avp_model, 0)); + struct dict_avp_request_ex avpreq; + memset(&avpreq, 0, sizeof(avpreq)); + avpreq.avp_vendor.vendor_id = avp->avp_public.avp_vendor; + avpreq.avp_data.avp_code = avp->avp_public.avp_code; + CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_STRUCT, &avpreq, &avp->avp_model, 0)); } else { /* no vendor */ CHECK_FCT( fd_dict_search ( dict, DICT_AVP, AVP_BY_CODE, &avp->avp_public.avp_code, &avp->avp_model, 0));