changeset 903:4382d7420e65

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.
author Sebastien Decugis <sdecugis@freediameter.net>
date Fri, 14 Dec 2012 21:24:34 +0100
parents 42d0a08cffa8
children b839a1b1c1da
files include/freeDiameter/libfdproto.h libfdproto/dictionary.c libfdproto/messages.c
diffstat 3 files changed, 63 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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 :
 
--- 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;
--- 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));
"Welcome to our mercurial repository"