Mercurial > hg > freeDiameter
changeset 156:e2dc300819b3
Fix overwriten thread location
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 20 Jan 2010 16:04:25 +0900 |
parents | 30a7252cbb55 |
children | 2b3a1ff2ed10 |
files | freeDiameter/cnxctx.c freeDiameter/dict_base_proto.c freeDiameter/sctps.c include/freeDiameter/libfreeDiameter.h libfreeDiameter/dictionary.c libfreeDiameter/fifo.c libfreeDiameter/libfD.h libfreeDiameter/messages.c |
diffstat | 8 files changed, 201 insertions(+), 181 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/cnxctx.c Tue Jan 19 11:41:01 2010 +0900 +++ b/freeDiameter/cnxctx.c Wed Jan 20 16:04:25 2010 +0900 @@ -1257,7 +1257,7 @@ if (conn->cc_tls) { #ifndef DISABLE_SCTP if (conn->cc_sctp_para.pairs > 1) { - /* Master session */ + /* Bye on master session */ CHECK_GNUTLS_DO( gnutls_bye(conn->cc_tls_para.session, GNUTLS_SHUT_WR), /* Continue */ ); /* and other stream pairs */
--- a/freeDiameter/dict_base_proto.c Tue Jan 19 11:41:01 2010 +0900 +++ b/freeDiameter/dict_base_proto.c Wed Jan 20 16:04:25 2010 +0900 @@ -143,6 +143,20 @@ return 0; } +static void Address_dump(union avp_value * avp_value) +{ + fd_log_debug("*todo: dump address*"); +} + +static void UTF8String_dump(union avp_value * avp_value) +{ + size_t len = avp_value->os.len; + if (len > 42) + len = 42; /* avoid very long strings */ + fd_log_debug("%.*s", len, avp_value->os.data); +} + + #define CHECK_dict_new( _type, _data, _parent, _ref ) \ @@ -230,7 +244,7 @@ defined in [IANAADFAM]. The AddressType is used to discriminate the content and format of the remaining octets. */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Address" , Address_interpret , Address_encode }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Address" , Address_interpret , Address_encode, Address_dump }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } @@ -249,7 +263,7 @@ SNTP [RFC4330] describes a procedure to extend the time to 2104. This procedure MUST be supported by all DIAMETER nodes. */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Time" , NULL , NULL }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "Time" , NULL , NULL , NULL }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } @@ -287,7 +301,7 @@ Note that the AVP Length field of an UTF8String is measured in octets, not characters. */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "UTF8String" , NULL , NULL }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "UTF8String" , NULL , NULL , UTF8String_dump }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } @@ -316,7 +330,7 @@ interactions between the Diameter protocol and Internationalized Domain Name (IDNs). */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterIdentity" , NULL , NULL }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterIdentity" , NULL , NULL , UTF8String_dump }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } @@ -371,7 +385,7 @@ aaa://host.example.com:6666;transport=tcp;protocol=diameter aaa://host.example.com:1813;transport=udp;protocol=radius */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterURI" , NULL , NULL }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "DiameterURI" , NULL , NULL , UTF8String_dump }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } @@ -433,7 +447,7 @@ supplied rules, for example to protect the access device owner's infrastructure. */ - struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "IPFilterRule" , NULL , NULL }; + struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "IPFilterRule" , NULL , NULL , UTF8String_dump }; CHECK_dict_new( DICT_TYPE, &data , NULL, NULL); } } @@ -603,7 +617,7 @@ with above result code SHOULD NOT attempt reconnection. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Disconnect-Cause)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Disconnect-Cause)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "REBOOTING", { .i32 = 0 }}; struct dict_enumval_data t_1 = { "BUSY", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "DO_NOT_WANT_TO_TALK_TO_YOU", { .i32 = 2 }}; @@ -908,7 +922,7 @@ */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Inband-Security-Id)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Inband-Security-Id)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "NO_INBAND_SECURITY", { .u32 = ACV_ISI_NO_INBAND_SECURITY }}; struct dict_enumval_data t_1 = { "TLS", { .u32 = ACV_ISI_TLS }}; struct dict_avp_data data = { @@ -1102,7 +1116,7 @@ 6. ALL_HOST */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Host-Usage)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Host-Usage)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "DONT_CACHE", { .i32 = 0 }}; struct dict_enumval_data t_1 = { "ALL_SESSION", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "ALL_REALM", { .i32 = 2 }}; @@ -1196,7 +1210,7 @@ * This is the reason for the "*" in the type name */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Result-Code)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Result-Code)" , NULL, NULL, NULL }; struct dict_avp_data data = { 268, /* Code */ #if AC_RESULT_CODE != 268 @@ -1795,7 +1809,7 @@ * This is the reason for the "*" in the type name. Vendors will have to define their values. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Experimental-Result-Code)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Experimental-Result-Code)" , NULL, NULL, NULL }; struct dict_avp_data data = { 298, /* Code */ 0, /* Vendor */ @@ -1842,7 +1856,7 @@ offered. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Request-Type)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Request-Type)" , NULL, NULL, NULL }; struct dict_enumval_data t_1 = { "AUTHENTICATE_ONLY", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "AUTHORIZE_ONLY", { .i32 = 2 }}; struct dict_enumval_data t_3 = { "AUTHORIZE_AUTHENTICATE", { .i32 = 3 }}; @@ -1984,7 +1998,7 @@ Authorization-Lifetime. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Session-State)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Auth-Session-State)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "STATE_MAINTAINED", { .i32 = 0 }}; struct dict_enumval_data t_1 = { "NO_STATE_MAINTAINED", { .i32 = 1 }}; struct dict_avp_data data = { @@ -2027,7 +2041,7 @@ expiration of the Authorization-Lifetime. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Re-Auth-Request-Type)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Re-Auth-Request-Type)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "AUTHORIZE_ONLY", { .i32 = 0 }}; struct dict_enumval_data t_1 = { "AUTHORIZE_AUTHENTICATE", { .i32 = 1 }}; struct dict_avp_data data = { @@ -2154,7 +2168,7 @@ The user's session has timed out, and service has been terminated. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Termination-Cause)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Termination-Cause)" , NULL, NULL, NULL }; struct dict_enumval_data t_1 = { "DIAMETER_LOGOUT", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "DIAMETER_SERVICE_NOT_PROVIDED", { .i32 = 2 }}; struct dict_enumval_data t_3 = { "DIAMETER_BAD_ANSWER", { .i32 = 3 }}; @@ -2266,7 +2280,7 @@ */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Session-Binding)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated*(Session-Binding)" , NULL, NULL, NULL }; struct dict_enumval_data t_1 = { "RE_AUTH", { .u32 = 1 }}; struct dict_enumval_data t_2 = { "STR", { .u32 = 2 }}; struct dict_enumval_data t_4 = { "ACCOUNTING", { .u32 = 4 }}; @@ -2328,7 +2342,7 @@ session. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Session-Server-Failover)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Session-Server-Failover)" , NULL, NULL, NULL }; struct dict_enumval_data t_0 = { "REFUSE_SERVICE", { .i32 = 0 }}; struct dict_enumval_data t_1 = { "TRY_AGAIN", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "ALLOW_SERVICE", { .i32 = 2 }}; @@ -2460,7 +2474,7 @@ the existing session. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Record-Type)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Record-Type)" , NULL, NULL, NULL }; struct dict_enumval_data t_1 = { "EVENT_RECORD", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "START_RECORD", { .i32 = 2 }}; struct dict_enumval_data t_3 = { "INTERIM_RECORD", { .i32 = 3 }}; @@ -2654,7 +2668,7 @@ stored. */ struct dict_object * type; - struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Realtime-Required)" , NULL, NULL}; + struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Realtime-Required)" , NULL, NULL, NULL }; struct dict_enumval_data t_1 = { "DELIVER_AND_GRANT", { .i32 = 1 }}; struct dict_enumval_data t_2 = { "GRANT_AND_STORE", { .i32 = 2 }}; struct dict_enumval_data t_3 = { "GRANT_AND_LOSE", { .i32 = 3 }};
--- a/freeDiameter/sctps.c Tue Jan 19 11:41:01 2010 +0900 +++ b/freeDiameter/sctps.c Wed Jan 20 16:04:25 2010 +0900 @@ -90,7 +90,12 @@ switch (event) { case FDEVP_CNX_MSG_RECV: /* Demux this message in the appropriate fifo, another thread will pull, gnutls process, and send in target queue */ - CHECK_FCT_DO(fd_event_send(conn->cc_sctps_data.array[strid].raw_recv, event, bufsz, buf), goto error ); + if (strid < conn->cc_sctp_para.pairs) { + CHECK_FCT_DO(fd_event_send(conn->cc_sctps_data.array[strid].raw_recv, event, bufsz, buf), goto error ); + } else { + TRACE_DEBUG(INFO, "Received packet (%d bytes) on out-of-range stream #%s from %s, discarded.", bufsz, strid, conn->cc_remid); + free(buf); + } break; case FDEVP_CNX_EP_CHANGE: @@ -112,6 +117,12 @@ if (!conn->cc_closing) { CHECK_FCT_DO( fd_event_send( Target_Queue(conn), FDEVP_CNX_ERROR, 0, NULL), /* continue or destroy everything? */); } + + /* Since the demux thread terminates, we must trig an error for all decipher threads. We do this by destroying all demuxed FIFO queues */ + for (strid = 0; strid < conn->cc_sctp_para.pairs; strid++) { + fd_event_destroy( &conn->cc_sctps_data.array[strid].raw_recv, free ); + } + goto out; } @@ -582,37 +593,16 @@ return 0; } -static void * bye_th(void * arg) -{ - struct sctps_ctx * ctx = (struct sctps_ctx *) arg; - TRACE_ENTRY("%p", arg); - - /* Set the thread name */ - { - char buf[48]; - snprintf(buf, sizeof(buf), "gnutls_bye (%hu@%d)", ctx->strid, ctx->parent->cc_socket); - fd_log_threadname ( buf ); - } - - CHECK_GNUTLS_DO( gnutls_bye(ctx->session, GNUTLS_SHUT_WR), /* Continue */ ); - - /* Finish */ - return NULL; -} - -/* Initiate a "bye" on all stream pairs in paralel */ +/* Initiate a "bye" on all stream pairs */ void fd_sctps_bye(struct cnxctx * conn) { uint16_t i; CHECK_PARAMS_DO( conn && conn->cc_sctps_data.array, return ); - /* End all TLS sessions, in parallel */ + /* End all TLS sessions, in series (not as efficient as paralel, but simpler) */ for (i = 1; i < conn->cc_sctp_para.pairs; i++) { - CHECK_POSIX_DO( pthread_create( &conn->cc_sctps_data.array[i].thr, NULL, bye_th, &conn->cc_sctps_data.array[i] ), break ); - } - for (--i; i > 0; --i) { - CHECK_POSIX_DO( pthread_join( conn->cc_sctps_data.array[i].thr, NULL ), continue ); + CHECK_GNUTLS_DO( gnutls_bye(conn->cc_sctps_data.array[i].session, GNUTLS_SHUT_WR), /* Continue */ ); } } @@ -676,7 +666,8 @@ /* Free remaining data in the array */ for (i = 0; i < conn->cc_sctp_para.pairs; i++) { - fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free ); + if (conn->cc_sctps_data.array[i].raw_recv) + fd_event_destroy( &conn->cc_sctps_data.array[i].raw_recv, free ); free(conn->cc_sctps_data.array[i].partial.buf); if (i > 0) gnutls_deinit(conn->cc_sctps_data.array[i].session);
--- a/include/freeDiameter/libfreeDiameter.h Tue Jan 19 11:41:01 2010 +0900 +++ b/include/freeDiameter/libfreeDiameter.h Wed Jan 20 16:04:25 2010 +0900 @@ -665,7 +665,6 @@ void fd_dict_dump_object(struct dict_object * obj); void fd_dict_dump(struct dictionary * dict); - /* *************************************************************************** * @@ -894,6 +893,7 @@ char *type_name; /* The name of this type */ dict_avpdata_interpret type_interpret;/* cb to convert the AVP value in more comprehensive format (or NULL) */ dict_avpdata_encode type_encode; /* cb to convert formatted data into an AVP value (or NULL) */ + void (*type_dump)(union avp_value * val); /* cb called by fd_msg_dump_one for this type of data (if != NULL) */ }; /* The criteria for searching a type object in the dictionary */
--- a/libfreeDiameter/dictionary.c Tue Jan 19 11:41:01 2010 +0900 +++ b/libfreeDiameter/dictionary.c Wed Jan 20 16:04:25 2010 +0900 @@ -1283,6 +1283,152 @@ CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); } +/**************************** Dump AVP values ********************************/ + +/* Default dump functions */ +static void dump_val_os(union avp_value * value) +{ + int i; + for (i = 0; i < value->os.len; i++) { + if (i == 16) { /* Dump only up to 16 bytes of the buffer */ + fd_log_debug("(trunc, len=%zd)", value->os.len); + break; + } + fd_log_debug("%02.2X ", value->os.data[i]); + } +} + +static void dump_val_i32(union avp_value * value) +{ + fd_log_debug("%i", value->i32); +} + +static void dump_val_i64(union avp_value * value) +{ + fd_log_debug("%lli (0x%llx)", value->i64, value->i64); +} + +static void dump_val_u32(union avp_value * value) +{ + fd_log_debug("%u", value->u32); +} + +static void dump_val_u64(union avp_value * value) +{ + fd_log_debug("%llu", value->u64); +} + +static void dump_val_f32(union avp_value * value) +{ + fd_log_debug("%f", value->f32); +} + +static void dump_val_f64(union avp_value * value) +{ + fd_log_debug("%g", value->f64); +} + +/* Get the dump function for basic dict_avp_basetype */ +static void (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *) +{ + switch (datatype) { + case AVP_TYPE_OCTETSTRING: + return &dump_val_os; + + case AVP_TYPE_INTEGER32: + return &dump_val_i32; + + case AVP_TYPE_INTEGER64: + return &dump_val_i64; + + case AVP_TYPE_UNSIGNED32: + return &dump_val_u32; + + case AVP_TYPE_UNSIGNED64: + return &dump_val_u64; + + case AVP_TYPE_FLOAT32: + return &dump_val_f32; + + case AVP_TYPE_FLOAT64: + return &dump_val_f64; + + case AVP_TYPE_GROUPED: + TRACE_DEBUG(FULL, "error: grouped AVP with a value!"); + } + return NULL; +} + +/* indent inside an object (duplicate from messages.c) */ +#define INOBJHDR "%*s " +#define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" + +/* Formater for the AVP value dump line */ +static void dump_avp_val(union avp_value *avp_value, void (*dump_val_cb)(union avp_value *avp_value), enum dict_avp_basetype datatype, char * type_name, char * const_name, int indent) +{ + /* Header for all AVP values dumps: */ + fd_log_debug(INOBJHDR "value ", INOBJHDRVAL); + + /* If the type is provided, write it */ + if (type_name) + fd_log_debug("t: '%s' ", type_name); + + /* Always give the base datatype anyway */ + fd_log_debug("(%s) ", type_base_name[datatype]); + + /* Now, the value */ + fd_log_debug("v: "); + if (const_name) + fd_log_debug("'%s' (", const_name); + (*dump_val_cb)(avp_value); + if (const_name) + fd_log_debug(")"); + + /* Done! */ + fd_log_debug("\n"); +} + +/* Dump the value of an AVP of known type */ +void fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent) +{ + void (*dump_val_cb)(union avp_value *avp_value); + struct dict_object * type = NULL; + char * type_name = NULL; + char * const_name = NULL; + + /* Check the parameters are correct */ + CHECK_PARAMS_DO( avp_value && verify_object(model) && (model->type == DICT_AVP), return ); + + /* Default: display the value with the formatter for the AVP datatype */ + CHECK_PARAMS_DO( dump_val_cb = get_default_dump_val_cb(model->data.avp.avp_basetype), return ); + + /* Get the type definition of this AVP */ + type = model->parent; + if (type) { + struct dict_enumval_request request; + struct dict_object * enumval = NULL; + + type_name = type->data.type.type_name; + + /* overwrite the dump function ? */ + if (type->data.type.type_dump) + dump_val_cb = type->data.type.type_dump; + + /* Now check if the AVP value matches a constant */ + memset(&request, 0, sizeof(request)); + request.type_obj = type; + memcpy(&request.search.enum_value, avp_value, sizeof(union avp_value)); + /* bypass checks */ + if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { + /* We found a cosntant, get its name */ + const_name = enumval->data.enumval.enum_name; + } + } + + /* And finally, dump the value */ + dump_avp_val(avp_value, dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent); +} + /*******************************************************************************************************/ /*******************************************************************************************************/ /* */
--- a/libfreeDiameter/fifo.c Tue Jan 19 11:41:01 2010 +0900 +++ b/libfreeDiameter/fifo.c Wed Jan 20 16:04:25 2010 +0900 @@ -158,6 +158,7 @@ /* Ok, now invalidate the queue */ q->eyec = 0xdead; + /* Have all waiting threads return an error */ while (q->thrs) { CHECK_POSIX( pthread_mutex_unlock( &q->mtx )); CHECK_POSIX( pthread_cond_signal(&q->cond) );
--- a/libfreeDiameter/libfD.h Tue Jan 19 11:41:01 2010 +0900 +++ b/libfreeDiameter/libfD.h Wed Jan 20 16:04:25 2010 +0900 @@ -51,6 +51,7 @@ /* Dispatch / messages / dictionary API */ int fd_dict_disp_cb(enum dict_object_type type, struct dict_object *obj, struct fd_list ** cb_list); +void fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent); int fd_disp_call_cb_int( struct fd_list * cb_list, struct msg ** msg, struct avp *avp, struct session *sess, enum disp_action *action, struct dict_object * obj_app, struct dict_object * obj_cmd, struct dict_object * obj_avp, struct dict_object * obj_enu); extern pthread_rwlock_t fd_disp_lock;
--- a/libfreeDiameter/messages.c Tue Jan 19 11:41:01 2010 +0900 +++ b/libfreeDiameter/messages.c Wed Jan 20 16:04:25 2010 +0900 @@ -690,99 +690,6 @@ INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_sess, msg->msg_src_id?:"(nil)"); } -#define DUMP_VALUE(_format, _parms...) fd_log_debug(INOBJHDR "value : t:'%s' v:'" _format "'\n", INOBJHDRVAL, typename, ## _parms); -/* Dump an AVP value that is not a constant */ -static void dump_basic_type(union avp_value * value, enum dict_avp_basetype type, const char * typename, int indent) -{ - switch (type) { - case AVP_TYPE_GROUPED: - DUMP_VALUE("%s", "error: grouped AVP with a value!"); - break; - - case AVP_TYPE_OCTETSTRING: - { - /* Dump only up to 16 bytes of the buffer */ - unsigned char buf[8]; - memset(buf, 0, sizeof(buf)); - memcpy(buf, value->os.data, value->os.len < sizeof(buf) ? value->os.len : sizeof(buf) ); - DUMP_VALUE("l:%d, v:%02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X %02.2X ... ('%.*s')", - value->os.len, - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], - value->os.len, value->os.data - ); - } - break; - - case AVP_TYPE_INTEGER32: - DUMP_VALUE("%i",value->i32); - break; - - case AVP_TYPE_INTEGER64: - DUMP_VALUE("%lli (0x%llx)",value->i64,value->i64); - break; - - case AVP_TYPE_UNSIGNED32: - DUMP_VALUE("%u",value->u32); - break; - - case AVP_TYPE_UNSIGNED64: - DUMP_VALUE("%llu",value->u64); - break; - - case AVP_TYPE_FLOAT32: - DUMP_VALUE("%f",value->f32); - break; - - case AVP_TYPE_FLOAT64: - DUMP_VALUE("%g",value->f64); - break; - - default: - DUMP_VALUE("%s %d", "error: invalid type :", type); - } -} - -/* Dump an AVP value that is a constant */ -#define DUMP_CONST(_format, _parms...) fd_log_debug(INOBJHDR "value : t:'%s' v:'%s' ( " _format " )\n", INOBJHDRVAL, typename, value->enum_name, ## _parms); -static void dump_constant_type(struct dict_enumval_data * value, enum dict_avp_basetype type, char * typename, int indent) -{ - switch (type) { - case AVP_TYPE_GROUPED: - DUMP_CONST("%s", "error: grouped AVP with a constant value!"); - break; - case AVP_TYPE_OCTETSTRING: - DUMP_CONST("%s", "value skipped"); - break; - - case AVP_TYPE_INTEGER32: - DUMP_CONST("%i",value->enum_value.i32); - break; - - case AVP_TYPE_INTEGER64: - DUMP_CONST("%li",value->enum_value.i64); - break; - - case AVP_TYPE_UNSIGNED32: - DUMP_CONST("%u",value->enum_value.u32); - break; - - case AVP_TYPE_UNSIGNED64: - DUMP_CONST("%lu",value->enum_value.u64); - break; - - case AVP_TYPE_FLOAT32: - DUMP_CONST("%f",value->enum_value.f32); - break; - - case AVP_TYPE_FLOAT64: - DUMP_CONST("%g",value->enum_value.f64); - break; - - default: - DUMP_CONST("%s %d", "error: invalid type :", type); - } -} - /* Dump an avp object */ static void obj_dump_avp ( struct avp * avp, int indent ) { @@ -833,47 +740,7 @@ if (!avp->avp_model) { fd_log_debug(INOBJHDR "(data set but no model: ERROR)\n", INOBJHDRVAL); } else { - /* Try and find a constant name for this value */ - struct dictionary * dict = NULL; - struct dict_object * avp_type = NULL; - struct dict_object * avp_constant = NULL; - struct dict_type_data type_data; - struct dict_enumval_request request; - ret = fd_dict_getdict(avp->avp_model, & dict); - if (ret != 0) { - dump_basic_type(avp->avp_public.avp_value, type, type_base_name[type], indent); - goto end; - } - ret = fd_dict_search(dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &avp_type, ENOENT); - if (ret != 0) { - dump_basic_type(avp->avp_public.avp_value, type, type_base_name[type], indent); - goto end; - } - ret = fd_dict_getval(avp_type, &type_data); - if (ret != 0) { - dump_basic_type(avp->avp_public.avp_value, type, "(error getting type data)", indent); - goto end; - } - if (type_data.type_base != type) { - dump_basic_type(avp->avp_public.avp_value, type, "(mismatching type information!)", indent); - goto end; - } - /* Create a query for a constant */ - memset(&request, 0, sizeof(request)); - request.type_obj = avp_type; - memcpy(&request.search.enum_value, avp->avp_public.avp_value, sizeof(union avp_value)); - ret = fd_dict_search(dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &request, &avp_constant, ENOENT); - if (ret != 0) { - dump_basic_type(avp->avp_public.avp_value, type, type_data.type_name, indent); - goto end; - } - /* get the constant's information; we re-use request.search field */ - ret = fd_dict_getval(avp_constant, &request.search); - if (ret != 0) { - dump_basic_type(avp->avp_public.avp_value, type, "(error getting constant data)", indent); - goto end; - } - dump_constant_type(&request.search, type, type_data.type_name, indent); + fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent); } } end: