# HG changeset patch # User Sebastien Decugis # Date 1244711297 -32400 # Node ID 7b3d4431610ae50b19d0c9b37290bbc0bd04b2ba # Parent 9cb1799c40d16a0fd23bdff670f9500f9d29ae10 Improved support for creating error messages, even when no dictionary definition is present diff -r 9cb1799c40d1 -r 7b3d4431610a include/waaad/message-api.h --- a/include/waaad/message-api.h Thu Jun 11 16:59:45 2009 +0900 +++ b/include/waaad/message-api.h Thu Jun 11 18:08:17 2009 +0900 @@ -106,7 +106,8 @@ /* Flags for the msg_new and msg_avp_new functions */ #define MSGFL_FROM_TEMPLATE 0x01 /* When creating an object, if it can contain children, also create the children using the "template" values in the dictionary */ #define MSGFL_ALLOW_ETEID 0x02 /* When creating a message, a new end-to-end ID is allocated and set in the message */ -#define MSGFL_MAX MSGFL_ALLOW_ETEID /* The biggest valid flag value */ +#define MSGFL_ANSW_ERROR 0x04 /* When creating an answer message, set the 'E' bit and use the generic error ABNF instead of command-specific ABNF */ +#define MSGFL_MAX MSGFL_ANSW_ERROR /* The biggest valid flag value */ #ifndef IN_EXTENSION diff -r 9cb1799c40d1 -r 7b3d4431610a waaad/message.c --- a/waaad/message.c Thu Jun 11 16:59:45 2009 +0900 +++ b/waaad/message.c Thu Jun 11 18:08:17 2009 +0900 @@ -1502,12 +1502,24 @@ qry = _M(*msg); /* Find the model for the answer */ - CHECK_FCT( _mpd_do_msg(qry, 0, 1) ); - CHECK_FCT( dict_search ( DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL ) ); + if (flags & MSGFL_ANSW_ERROR) { + /* The model is the generic error format */ + model = dict_cmd_error; + } else { + /* The model is the answer corresponding to the query. It supposes that these are defined in the dictionary */ + CHECK_FCT( _mpd_do_msg(qry, 0, 1) ); + CHECK_FCT( dict_search ( DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL ) ); + } /* Create the answer */ CHECK_FCT( msg_new( model, flags, msg ) ); + /* Set informations in the answer as in the query */ + _M(*msg)->msg_public.msg_code = qry->msg_public.msg_code; /* useful for MSGFL_ANSW_ERROR */ + _M(*msg)->msg_public.msg_appl = qry->msg_public.msg_appl; + _M(*msg)->msg_public.msg_eteid = qry->msg_public.msg_eteid; + _M(*msg)->msg_public.msg_hbhid = qry->msg_public.msg_hbhid; + /* associate with query */ /* may do that but this is faster... CHECK_FCT( msg_answ_associate( *msg, (msg_t *)qry ) ); */ _M(*msg)->msg_query = (msg_t *)qry; @@ -2320,8 +2332,8 @@ return 0; } -/* Create an anwer to a query */ -int msg_new_answer_from_req ( msg_t ** msg ) +/* Create an anwer to a query, possibly an error message */ +int msg_new_answer_from_req ( msg_t ** msg, int error ) { _msg_t *qry; @@ -2333,7 +2345,7 @@ CHECK_PARAMS( qry->msg_public.msg_flags & CMD_FLAG_REQUEST ); /* Create the new message */ - CHECK_FCT( msg_new_answ(msg, 0) ); + CHECK_FCT( msg_new_answ(msg, error ? MSGFL_ANSW_ERROR : 0) ); /* If the first AVP of the query is a Session-Id, copy it to the answer */ { @@ -2463,12 +2475,15 @@ } - if (set_e_bit) { + { msg_data_t * hdr = NULL; CHECK_FCT( msg_data( msg, &hdr ) ); - hdr->msg_flags |= CMD_FLAG_ERROR; + if (set_e_bit) + hdr->msg_flags |= CMD_FLAG_ERROR; + else + hdr->msg_flags &= ! CMD_FLAG_ERROR; } if (std_err_msg || errormsg) { diff -r 9cb1799c40d1 -r 7b3d4431610a waaad/message.h --- a/waaad/message.h Thu Jun 11 16:59:45 2009 +0900 +++ b/waaad/message.h Thu Jun 11 18:08:17 2009 +0900 @@ -197,6 +197,7 @@ * * PARAMETERS: * msg : The location of the query on entry, and of answer on return. + * error : Boolean to indicate if the answer is an error message (with 'E' bit set) * * DESCRIPTION: * This function creates the empty answer message for a request. @@ -209,7 +210,7 @@ * 0 : Operation complete. * !0 : an error occurred. */ -int msg_new_answer_from_req ( msg_t ** msg ); +int msg_new_answer_from_req ( msg_t ** msg, int error ); /* * FUNCTION: msg_rescode_set diff -r 9cb1799c40d1 -r 7b3d4431610a waaad/routing.c --- a/waaad/routing.c Thu Jun 11 16:59:45 2009 +0900 +++ b/waaad/routing.c Thu Jun 11 18:08:17 2009 +0900 @@ -563,7 +563,7 @@ if (is_req) { /* Create the answer message */ - CHECK_FCT_DO( msg_new_answer_from_req(&msg), goto error ); + CHECK_FCT_DO( msg_new_answer_from_req(&msg, 1), goto error ); /* Set the result code */ CHECK_FCT_DO( msg_rescode_set(msg, "DIAMETER_APPLICATION_UNSUPPORTED", NULL, NULL, 1), goto error ); @@ -706,7 +706,7 @@ msg_dump_walk(FULL, msg); /* Create the answer message */ - CHECK_FCT_DO( msg_new_answer_from_req(&msg), goto error ); + CHECK_FCT_DO( msg_new_answer_from_req(&msg, 1), goto error ); /* Set the result code */ CHECK_FCT_DO( msg_rescode_set(msg, "DIAMETER_UNABLE_TO_DELIVER", NULL, NULL, 1), goto error ); diff -r 9cb1799c40d1 -r 7b3d4431610a waaad/tests/testrt.c --- a/waaad/tests/testrt.c Thu Jun 11 16:59:45 2009 +0900 +++ b/waaad/tests/testrt.c Thu Jun 11 18:08:17 2009 +0900 @@ -288,7 +288,7 @@ alarm(2); /* Now create an answer to that message */ - CHECK( 0, msg_new_answer_from_req( &msg ) ); + CHECK( 0, msg_new_answer_from_req( &msg, 0 ) ); CHECK( 0, msg_rescode_set( msg, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); /* Do as if we had received this answer; it must be forwarded to peer1 */