Navigation


Changes in / [1453:05185ab84cf8:1449:ffe2f27e00e5] in freeDiameter


Ignore:
Files:
3 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • extensions/CMakeLists.txt

    r1452 r1436  
    9090
    9191FD_EXTENSION_SUBDIR(dbg_dict_dump   "Log dictionary dump"                            ON)
    92 FD_EXTENSION_SUBDIR(dbg_dict_dump_json   "Dump dictionary as JSON"                            ON)
    9392FD_EXTENSION_SUBDIR(dbg_loglevel "Read loglevel from file -- allows runtime change"  ON)
    9493FD_EXTENSION_SUBDIR(dbg_monitor     "Outputs periodical status information"              ON)
  • freeDiameterd/main.c

    r1450 r1412  
    9191        }
    9292
    93         /* Cleanup pidfile on exit */
     93        /* Cleaup pidfile on exit */
    9494        if (atexit(pidfile_cleanup) != 0) {
    9595                LOG_F("Unable to setup pidfile cleanup");
  • libfdproto/dictionary.c

    r1451 r1444  
    3535
    3636#include "fdproto-internal.h"
    37 #include "dictionary-internal.h"
    3837#include <inttypes.h>
    3938
     
    5049        };
    5150
     51/* The number of lists in an object */
     52#define NB_LISTS_PER_OBJ        3
     53
    5254/* Some eye catchers definitions */
    5355#define OBJECT_EYECATCHER       (0x0b13c7)
    5456#define DICT_EYECATCHER         (0x00d1c7)
     57
     58/* Definition of the dictionary objects */
     59struct dict_object {
     60        enum dict_object_type   type;   /* What type of object is this? */
     61        int                     objeyec;/* eyecatcher for this object */
     62        int                     typeyec;/* eyecatcher for this type of object */
     63        struct dictionary       *dico;  /* The dictionary this object belongs to */
     64       
     65        union {
     66                struct dict_vendor_data         vendor;         /* datastr_len = strlen(vendor_name) */
     67                struct dict_application_data    application;    /* datastr_len = strlen(application_name) */
     68                struct dict_type_data           type;           /* datastr_len = strlen(type_name) */
     69                struct dict_enumval_data        enumval;        /* datastr_len = strlen(enum_name) */
     70                struct dict_avp_data            avp;            /* datastr_len = strlen(avp_name) */
     71                struct dict_cmd_data            cmd;            /* datastr_len = strlen(cmd_name) */
     72                struct dict_rule_data           rule;           /* datastr_len = 0 */
     73        } data;                         /* The data of this object */
     74       
     75        size_t                  datastr_len; /* cached length of the string inside the data. Saved when the object is created. */
     76       
     77        struct dict_object *    parent; /* The parent of this object, if any */
     78       
     79        struct fd_list          list[NB_LISTS_PER_OBJ];/* used to chain objects.*/
     80        /* More information about the lists :
     81       
     82         - the use for each list depends on the type of object. See detail below.
     83         
     84         - a sentinel for a list has its 'o' field cleared. (this is the criteria to detect end of a loop)
     85         
     86         - The lists are always ordered. The criteria are described below. the functions to order them are referenced in dict_obj_info
     87         
     88         - The dict_lock must be held for any list operation.
     89         
     90         => VENDORS:
     91         list[0]: list of the vendors, ordered by their id. The sentinel is g_dict_vendors (vendor with id 0)
     92         list[1]: sentinel for the list of AVPs from this vendor, ordered by AVP code.
     93         list[2]: sentinel for the list of AVPs from this vendor, ordered by AVP name (fd_os_cmp).
     94         
     95         => APPLICATIONS:
     96         list[0]: list of the applications, ordered by their id. The sentinel is g_dict_applications (application with id 0)
     97         list[1]: not used
     98         list[2]: not used.
     99         
     100         => TYPES:
     101         list[0]: list of the types, ordered by their names. The sentinel is g_list_types.
     102         list[1]: sentinel for the type_enum list of this type, ordered by their constant name (fd_os_cmp).
     103         list[2]: sentinel for the type_enum list of this type, ordered by their constant value.
     104         
     105         => TYPE_ENUMS:
     106         list[0]: list of the contants for a given type, ordered by the constant name (fd_os_cmp). Sentinel is a (list[1]) element of a TYPE object.
     107         list[1]: list of the contants for a given type, ordered by the constant value. Sentinel is a (list[2]) element of a TYPE object.
     108         list[2]: not used
     109         
     110         => AVPS:
     111         list[0]: list of the AVP from a given vendor, ordered by avp code. Sentinel is a list[1] element of a VENDOR object.
     112         list[1]: list of the AVP from a given vendor, ordered by avp name (fd_os_cmp). Sentinel is a list[2] element of a VENDOR object.
     113         list[2]: sentinel for the rule list that apply to this AVP.
     114         
     115         => COMMANDS:
     116         list[0]: list of the commands, ordered by their names (fd_os_cmp). The sentinel is g_list_cmd_name.
     117         list[1]: list of the commands, ordered by their command code and 'R' flag. The sentinel is g_list_cmd_code.
     118         list[2]: sentinel for the rule list that apply to this command.
     119         
     120         => RULES:
     121         list[0]: list of the rules for a given (grouped) AVP or Command, ordered by the AVP vendor & code to which they refer. sentinel is list[2] of a command or (grouped) avp.
     122         list[1]: not used
     123         list[2]: not used.
     124         
     125         */
     126         
     127         /* Sentinel for the dispatch callbacks */
     128         struct fd_list         disp_cbs;
     129       
     130};
     131
     132/* Definition of the dictionary structure */
     133struct dictionary {
     134        int                     dict_eyec;              /* Eye-catcher for the dictionary (DICT_EYECATCHER) */
     135       
     136        pthread_rwlock_t        dict_lock;              /* The global rwlock for the dictionary */
     137       
     138        struct dict_object      dict_vendors;           /* Sentinel for the list of vendors, corresponding to vendor 0 */
     139        struct dict_object      dict_applications;      /* Sentinel for the list of applications, corresponding to app 0 */
     140        struct fd_list          dict_types;             /* Sentinel for the list of types */
     141        struct fd_list          dict_cmd_name;          /* Sentinel for the list of commands, ordered by names */
     142        struct fd_list          dict_cmd_code;          /* Sentinel for the list of commands, ordered by codes */
     143       
     144        struct dict_object      dict_cmd_error;         /* Special command object for answers with the 'E' bit set */
     145       
     146        int                     dict_count[DICT_TYPE_MAX + 1]; /* Number of objects of each type */
     147};
    55148
    56149/* Forward declarations of dump functions */
     
    85178} dict_obj_info[] = { { 0, "(error)", 0, 0, 0, 0, NULL, NULL, {0, 0, 0} }
    86179
    87         /* type                  name           datasize                          parent        parenttype
     180        /* type                  name           datasize                          parent        parenttype 
    88181                        eyecatcher              dump_data               search_fct,             haslist[]       */
    89182
    90183        ,{ DICT_VENDOR,         "VENDOR",       sizeof(struct dict_vendor_data),        0,      0,
    91184                        OBJECT_EYECATCHER + 1,  dump_vendor_data,       search_vendor,          { 1, 0, 0 } }
    92 
     185       
    93186        ,{ DICT_APPLICATION,    "APPLICATION",  sizeof(struct dict_application_data),   1,      DICT_VENDOR,
    94187                        OBJECT_EYECATCHER + 2,  dump_application_data,  search_application,     { 1, 0, 0 } }
    95 
     188       
    96189        ,{ DICT_TYPE,           "TYPE",         sizeof(struct dict_type_data),          1,      DICT_APPLICATION,
    97190                        OBJECT_EYECATCHER + 3,  dump_type_data,         search_type,            { 1, 0, 0 } }
    98 
     191       
    99192        ,{ DICT_ENUMVAL,        "ENUMVAL",      sizeof(struct dict_enumval_data),       2,      DICT_TYPE,
    100193                        OBJECT_EYECATCHER + 4,  NULL,                   search_enumval, { 1, 1, 0 } }
    101 
     194       
    102195        ,{ DICT_AVP,            "AVP",          sizeof(struct dict_avp_data),           1,      DICT_TYPE,
    103196                        OBJECT_EYECATCHER + 5,  dump_avp_data,          search_avp,             { 1, 1, 0 } }
    104 
     197       
    105198        ,{ DICT_COMMAND,        "COMMAND",      sizeof(struct dict_cmd_data),           1,      DICT_APPLICATION,
    106199                        OBJECT_EYECATCHER + 6,  dump_command_data,      search_cmd,             { 1, 1, 0 } }
    107 
     200       
    108201        ,{ DICT_RULE,           "RULE",         sizeof(struct dict_rule_data),          2,      -1 /* special case: grouped avp or command */,
    109202                        OBJECT_EYECATCHER + 7,  dump_rule_data,         search_rule,            { 1, 0, 0 } }
    110 
     203       
    111204};
    112 
     205       
    113206/* Macro to verify a "type" value */
    114207#define CHECK_TYPE( type ) ( ((type) > 0) && ((type) <= DICT_TYPE_MAX) )
     
    138231        str = os0dup( str, *(plen));            \
    139232}
    140 
     233       
    141234/* Initialize an object */
    142235static void init_object( struct dict_object * obj, enum dict_object_type type )
    143236{
    144237        int i;
    145 
     238       
    146239        TRACE_ENTRY("%p %d", obj, type);
    147 
     240       
    148241        /* Clean the object first */
    149242        memset ( obj, 0, sizeof(struct dict_object));
    150 
     243       
    151244        CHECK_PARAMS_DO(  CHECK_TYPE(type),  return  );
    152245
     
    156249
    157250        /* We don't initialize the data nor the parent here */
    158 
     251       
    159252        /* Now init the lists */
    160253        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
    161                 if (_OBINFO(obj).haslist[i] != 0)
     254                if (_OBINFO(obj).haslist[i] != 0) 
    162255                        fd_list_init(&obj->list[i], obj);
    163256                else
    164257                        fd_list_init(&obj->list[i], NULL);
    165258        }
    166 
     259       
    167260        fd_list_init(&obj->disp_cbs, NULL);
    168261}
     
    173266        TRACE_ENTRY("%p %p %d", dest, source, type);
    174267        CHECK_PARAMS( dest && source && CHECK_TYPE(type) );
    175 
    176         /* Generic: copy the full data structure */
     268       
     269        /* Generic: copy the full data structure */     
    177270        memcpy( &dest->data, source, dict_obj_info[type].datasize );
    178 
     271       
    179272        /* Then strings must be duplicated, not copied */
    180273        /* This function might be simplified by always defining the "name" field as the first field of the structures, but... it's error-prone */
     
    183276                        DUP_string_len( dest->data.vendor.vendor_name, &dest->datastr_len );
    184277                        break;
    185 
     278               
    186279                case DICT_APPLICATION:
    187280                        DUP_string_len( dest->data.application.application_name, &dest->datastr_len );
    188281                        break;
    189 
     282                       
    190283                case DICT_TYPE:
    191284                        DUP_string_len( dest->data.type.type_name, &dest->datastr_len );
    192285                        break;
    193 
     286                       
    194287                case DICT_ENUMVAL:
    195288                        DUP_string_len( dest->data.enumval.enum_name, &dest->datastr_len );
    196289                        if (dupos) {
    197290                                // we also need to duplicate the octetstring constant value since it is a pointer.
    198                                 dest->data.enumval.enum_value.os.data = os0dup(
    199                                                 ((struct dict_enumval_data *)source)->enum_value.os.data,
     291                                dest->data.enumval.enum_value.os.data = os0dup( 
     292                                                ((struct dict_enumval_data *)source)->enum_value.os.data, 
    200293                                                ((struct dict_enumval_data *)source)->enum_value.os.len
    201294                                        );
     
    206299                        DUP_string_len( dest->data.avp.avp_name, &dest->datastr_len );
    207300                        break;
    208 
     301                       
    209302                case DICT_COMMAND:
    210303                        DUP_string_len( dest->data.cmd.cmd_name, &dest->datastr_len );
    211304                        break;
    212 
     305               
    213306                default:
    214307                        /* Nothing to do for RULES */
    215308                        ;
    216309        }
    217 
     310       
    218311        return 0;
    219312}
     
    223316{
    224317        TRACE_ENTRY("%p", obj);
    225 
     318       
    226319        CHECK_PARAMS_DO(  obj
    227320                        && (obj->objeyec == OBJECT_EYECATCHER)
     
    241334                        return 0;
    242335                }  );
    243 
     336       
    244337        /* The object is probably valid. */
    245338        return 1;
     
    250343{
    251344        /* TRACE_ENTRY("%p", obj); */
    252 
     345       
    253346        switch (obj->type) {
    254347                case DICT_VENDOR:
    255348                        free( obj->data.vendor.vendor_name );
    256349                        break;
    257 
     350               
    258351                case DICT_APPLICATION:
    259352                        free( obj->data.application.application_name );
    260353                        break;
    261 
     354                       
    262355                case DICT_TYPE:
    263356                        free( obj->data.type.type_name );
    264357                        break;
    265 
     358                       
    266359                case DICT_ENUMVAL:
    267360                        free( obj->data.enumval.enum_name );
     
    271364                        free( obj->data.avp.avp_name );
    272365                        break;
    273 
     366                       
    274367                case DICT_COMMAND:
    275368                        free( obj->data.cmd.cmd_name );
    276369                        break;
    277 
     370               
    278371                default:
    279372                        /* nothing to do */
     
    286379
    287380/* Destroy all objects in a list - the lock must be held */
    288 static void destroy_list(struct fd_list * head)
     381static void destroy_list(struct fd_list * head) 
    289382{
    290383        /* TRACE_ENTRY("%p", head); */
    291 
     384       
    292385        /* loop in the list */
    293386        while (!FD_IS_LIST_EMPTY(head))
     
    297390        }
    298391}
    299 
     392       
    300393/* Free an object and its sublists */
    301394static void destroy_object(struct dict_object * obj)
    302395{
    303396        int i;
    304 
     397       
    305398        /* TRACE_ENTRY("%p", obj); */
    306 
     399       
    307400        /* Update global count */
    308         if (obj->dico)
     401        if (obj->dico) 
    309402                obj->dico->dict_count[obj->type]--;
    310 
     403       
    311404        /* Mark the object as invalid */
    312405        obj->objeyec = 0xdead;
    313 
     406       
    314407        /* First, destroy the data associated to the object */
    315408        destroy_object_data(obj);
    316 
     409       
    317410        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
    318411                if (_OBINFO(obj).haslist[i])
     
    323416                        destroy_list( &obj->list[i] );
    324417        }
    325 
     418       
    326419        /* Unlink all elements from the dispatch list; they will be freed when callback is unregistered */
    327420        CHECK_POSIX_DO( pthread_rwlock_wrlock(&fd_disp_lock), /* continue */ );
     
    330423        }
    331424        CHECK_POSIX_DO( pthread_rwlock_unlock(&fd_disp_lock), /* continue */ );
    332 
     425       
    333426        /* Last, destroy the object */
    334427        free(obj);
     
    345438/* Compare two values */
    346439#define ORDER_scalar( i1, i2 ) \
    347         ((i1 < i2 ) ? -1 : ( i1 > i2 ? 1 : 0 ))
     440        ((i1 < i2 ) ? -1 : ( i1 > i2 ? 1 : 0 )) 
    348441
    349442
     
    352445{
    353446        TRACE_ENTRY("%p %p", o1, o2);
    354 
     447       
    355448        return ORDER_scalar( o1->data.vendor.vendor_id, o2->data.vendor.vendor_id );
    356449}
     
    360453{
    361454        TRACE_ENTRY("%p %p", o1, o2);
    362 
     455       
    363456        return ORDER_scalar( o1->data.application.application_id, o2->data.application.application_id );
    364457}
     
    368461{
    369462        TRACE_ENTRY("%p %p", o1, o2);
    370 
     463       
    371464        return fd_os_cmp( o1->data.type.type_name, o1->datastr_len, o2->data.type.type_name, o2->datastr_len );
    372465}
     
    376469{
    377470        TRACE_ENTRY("%p %p", o1, o2);
    378 
     471       
    379472        return fd_os_cmp( o1->data.enumval.enum_name, o1->datastr_len, o2->data.enumval.enum_name, o2->datastr_len );
    380473}
     
    384477{
    385478        TRACE_ENTRY("%p %p", o1, o2);
    386 
     479       
    387480        /* The comparison function depends on the type of data */
    388481        switch ( o1->parent->data.type.type_base ) {
    389482                case AVP_TYPE_OCTETSTRING:
    390                         return fd_os_cmp( o1->data.enumval.enum_value.os.data, o1->data.enumval.enum_value.os.len,
     483                        return fd_os_cmp( o1->data.enumval.enum_value.os.data, o1->data.enumval.enum_value.os.len, 
    391484                                          o2->data.enumval.enum_value.os.data, o2->data.enumval.enum_value.os.len);
    392 
     485               
    393486                case AVP_TYPE_INTEGER32:
    394487                        return ORDER_scalar( o1->data.enumval.enum_value.i32, o2->data.enumval.enum_value.i32 );
     
    420513{
    421514        TRACE_ENTRY("%p %p", o1, o2);
    422 
     515       
    423516        return ORDER_scalar( o1->data.avp.avp_code, o2->data.avp.avp_code );
    424517}
     
    428521{
    429522        TRACE_ENTRY("%p %p", o1, o2);
    430 
     523       
    431524        return fd_os_cmp( o1->data.avp.avp_name, o1->datastr_len, o2->data.avp.avp_name, o2->datastr_len );
    432525}
     
    436529{
    437530        TRACE_ENTRY("%p %p", o1, o2);
    438 
     531       
    439532        return fd_os_cmp( o1->data.cmd.cmd_name, o1->datastr_len, o2->data.cmd.cmd_name, o2->datastr_len );
    440533}
     
    445538        uint8_t fl1, fl2;
    446539        int cmp = 0;
    447 
     540       
    448541        TRACE_ENTRY("%p %p", o1, o2);
    449 
     542       
    450543        cmp = ORDER_scalar( o1->data.cmd.cmd_code, o2->data.cmd.cmd_code );
    451         if (cmp)
     544        if (cmp) 
    452545                return cmp;
    453 
     546       
    454547        /* Same command code, we must compare the value of the 'R' flag */
    455548        fl1 = o1->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST;
    456549        fl2 = o2->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST;
    457 
     550       
    458551        /* We want requests first, so we reverse the operators here */
    459552        return ORDER_scalar(fl2, fl1);
    460 
     553               
    461554}
    462555
     
    465558{
    466559        TRACE_ENTRY("%p %p", o1, o2);
    467 
    468         return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor)
     560       
     561        return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor) 
    469562                ?: ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_code, o2->data.rule.rule_avp->data.avp.avp_code) ;
    470563}
     
    652745        int ret = 0;
    653746        vendor_id_t id;
    654 
     747       
    655748        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    656 
     749       
    657750        switch (criteria) {
    658751                case VENDOR_BY_ID:
     
    660753                        SEARCH_scalar( id, &dict->dict_vendors.list[0], vendor.vendor_id, 1, &dict->dict_vendors );
    661754                        break;
    662 
     755                               
    663756                case VENDOR_BY_NAME:
    664757                        /* "what" is a vendor name */
    665758                        SEARCH_os0( what, &dict->dict_vendors.list[0], vendor.vendor_name, 0);
    666759                        break;
    667 
     760                       
    668761                case VENDOR_OF_APPLICATION:
    669762                        /* "what" should be an application object */
    670763                        SEARCH_childs_parent( DICT_APPLICATION, &dict->dict_vendors );
    671764                        break;
    672 
     765               
    673766                case VENDOR_OF_AVP:
    674767                        /* "what" should be an avp object */
    675768                        SEARCH_sentinel( DICT_AVP, 0, 1 );
    676769                        break;
    677 
     770               
    678771                default:
    679772                        /* Invalid criteria */
     
    688781        int ret = 0;
    689782        application_id_t id;
    690 
     783       
    691784        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    692 
     785       
    693786        switch (criteria) {
    694787                case APPLICATION_BY_ID:
     
    697790                        SEARCH_scalar( id, &dict->dict_applications.list[0],  application.application_id, 1, &dict->dict_applications );
    698791                        break;
    699 
     792                               
    700793                case APPLICATION_BY_NAME:
    701794                        /* "what" is an application name */
    702795                        SEARCH_os0( what, &dict->dict_applications.list[0], application.application_name, 0);
    703796                        break;
    704 
     797                       
    705798                case APPLICATION_OF_TYPE:
    706799                        /* "what" should be a type object */
    707800                        SEARCH_childs_parent( DICT_TYPE, &dict->dict_applications );
    708801                        break;
    709 
     802               
    710803                case APPLICATION_OF_COMMAND:
    711804                        /* "what" should be a command object */
    712805                        SEARCH_childs_parent( DICT_COMMAND, &dict->dict_applications );
    713806                        break;
    714 
     807               
    715808                default:
    716809                        /* Invalid criteria */
     
    724817{
    725818        int ret = 0;
    726 
     819       
    727820        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    728 
     821       
    729822        switch (criteria) {
    730823                case TYPE_BY_NAME:
     
    732825                        SEARCH_os0( what, &dict->dict_types, type.type_name, 1);
    733826                        break;
    734 
     827                       
    735828                case TYPE_OF_ENUMVAL:
    736829                        /* "what" should be a type_enum object */
    737830                        SEARCH_childs_parent( DICT_ENUMVAL, NULL );
    738831                        break;
    739 
     832               
    740833                case TYPE_OF_AVP:
    741834                        /* "what" should be an avp object */
    742835                        SEARCH_childs_parent( DICT_AVP, NULL );
    743836                        break;
    744 
    745 
     837               
     838                               
    746839                default:
    747840                        /* Invalid criteria */
     
    755848{
    756849        int ret = 0;
    757 
     850       
    758851        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    759 
     852       
    760853        switch (criteria) {
    761854                case ENUMVAL_BY_STRUCT:
     
    763856                                struct dict_object * parent = NULL;
    764857                                struct dict_enumval_request * _what = (struct dict_enumval_request *) what;
    765 
     858                               
    766859                                CHECK_PARAMS(  _what  &&  ( _what->type_obj || _what->type_name )  );
    767 
     860                               
    768861                                if (_what->type_obj != NULL) {
    769862                                        parent = _what->type_obj;
     
    774867                                                        CHECK_PARAMS( 0 ) );
    775868                                }
    776 
     869                               
    777870                                /* From here the "parent" object is valid */
    778 
     871                               
    779872                                if ( _what->search.enum_name != NULL ) {
    780873                                        /* We are looking for this string */
     
    784877                                        switch (parent->data.type.type_base) {
    785878                                                case AVP_TYPE_OCTETSTRING:
    786                                                         SEARCH_os(       _what->search.enum_value.os.data,
    787                                                                          _what->search.enum_value.os.len,
    788                                                                          &parent->list[2],
    789                                                                          enumval.enum_value.os ,
     879                                                        SEARCH_os(       _what->search.enum_value.os.data, 
     880                                                                         _what->search.enum_value.os.len, 
     881                                                                         &parent->list[2], 
     882                                                                         enumval.enum_value.os , 
    790883                                                                         1 );
    791884                                                        break;
     
    798891                                                                        (struct dict_object *)NULL);
    799892                                                        break;
    800 
     893                                                       
    801894                                                case AVP_TYPE_INTEGER64:
    802895                                                        SEARCH_scalar(  _what->search.enum_value.i64,
     
    806899                                                                        (struct dict_object *)NULL);
    807900                                                        break;
    808 
     901                                                       
    809902                                                case AVP_TYPE_UNSIGNED32:
    810903                                                        SEARCH_scalar(  _what->search.enum_value.u32,
     
    814907                                                                        (struct dict_object *)NULL);
    815908                                                        break;
    816 
     909                                                       
    817910                                                case AVP_TYPE_UNSIGNED64:
    818911                                                        SEARCH_scalar(  _what->search.enum_value.u64,
     
    822915                                                                        (struct dict_object *)NULL);
    823916                                                        break;
    824 
     917                                                       
    825918                                                case AVP_TYPE_FLOAT32:
    826919                                                        SEARCH_scalar(  _what->search.enum_value.f32,
     
    830923                                                                        (struct dict_object *)NULL);
    831924                                                        break;
    832 
     925                                                       
    833926                                                case AVP_TYPE_FLOAT64:
    834927                                                        SEARCH_scalar(  _what->search.enum_value.f64,
     
    838931                                                                        (struct dict_object *)NULL);
    839932                                                        break;
    840 
     933                                                       
    841934                                                default:
    842935                                                        /* Invalid parent type basetype */
     
    844937                                        }
    845938                                }
    846 
     939                               
    847940                        }
    848941                        break;
    849 
    850 
     942               
     943                               
    851944                default:
    852945                        /* Invalid criteria */
     
    860953{
    861954        int ret = 0;
    862 
     955       
    863956        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    864 
     957       
    865958        switch (criteria) {
    866959                case AVP_BY_CODE:
     
    872965                        }
    873966                        break;
    874 
     967                               
    875968                case AVP_BY_NAME:
    876969                        /* "what" is the AVP name, vendor 0 */
    877970                        SEARCH_os0( what, &dict->dict_vendors.list[2], avp.avp_name, 1);
    878971                        break;
    879 
     972                       
    880973                case AVP_BY_CODE_AND_VENDOR:
    881974                case AVP_BY_NAME_AND_VENDOR:
     
    883976                                struct dict_avp_request * _what = (struct dict_avp_request *) what;
    884977                                struct dict_object * vendor = NULL;
    885 
     978                               
    886979                                CHECK_PARAMS( (criteria != AVP_BY_NAME_AND_VENDOR) || _what->avp_name  );
    887 
     980                               
    888981                                /* Now look for the vendor first */
    889982                                CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor, &vendor ) );
     
    895988                                        goto end;
    896989                                }
    897 
     990                               
    898991                                /* We now have our vendor = head of the appropriate avp list */
    899992                                if (criteria == AVP_BY_NAME_AND_VENDOR) {
     
    905998                        }
    906999                        break;
    907 
     1000               
    9081001                case AVP_BY_STRUCT:
    9091002                        {
    9101003                                struct dict_avp_request_ex * _what = (struct dict_avp_request_ex *) what;
    9111004                                struct dict_object * vendor = NULL;
    912 
     1005                               
    9131006                                CHECK_PARAMS( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name );
    9141007                                CHECK_PARAMS( _what->avp_data.avp_code || _what->avp_data.avp_name );
    915 
     1008                               
    9161009                                /* Now look for the vendor first */
    9171010                                if (_what->avp_vendor.vendor) {
     
    9241017                                        CHECK_FCT( search_vendor( dict, VENDOR_BY_NAME, _what->avp_vendor.vendor_name, &vendor ) );
    9251018                                }
    926 
     1019                               
    9271020                                if (vendor == NULL) {
    9281021                                        if (result)
     
    9321025                                        goto end;
    9331026                                }
    934 
     1027                               
    9351028                                /* We now have our vendor = head of the appropriate avp list */
    9361029                                if (_what->avp_data.avp_code) {
     
    9421035                        }
    9431036                        break;
    944 
     1037               
    9451038                case AVP_BY_NAME_ALL_VENDORS:
    9461039                        {
    9471040                                struct fd_list * li;
    9481041                                size_t wl = strlen((char *)what);
    949 
     1042                               
    9501043                                /* First, search for vendor 0 */
    9511044                                SEARCH_os0_l( what, wl, &dict->dict_vendors.list[2], avp.avp_name, 1);
    952 
     1045                               
    9531046                                /* If not found, loop for all vendors, until found */
    9541047                                for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) {
     
    9571050                        }
    9581051                        break;
    959 
     1052               
    9601053                default:
    9611054                        /* Invalid criteria */
     
    9691062{
    9701063        int ret = 0;
    971 
     1064       
    9721065        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    973 
     1066       
    9741067        switch (criteria) {
    9751068                case CMD_BY_NAME:
     
    9771070                        SEARCH_os0( what, &dict->dict_cmd_name, cmd.cmd_name, 1);
    9781071                        break;
    979 
     1072                       
    9801073                case CMD_BY_CODE_R:
    9811074                case CMD_BY_CODE_A:
     
    9831076                                command_code_t code;
    9841077                                uint8_t searchfl = 0;
    985 
     1078                               
    9861079                                /* The command code that we are searching */
    9871080                                code = *(command_code_t *) what;
    988 
     1081                               
    9891082                                /* The flag (request or answer) of the command we are searching */
    9901083                                if (criteria == CMD_BY_CODE_R) {
    9911084                                        searchfl = CMD_FLAG_REQUEST;
    9921085                                }
    993 
     1086                               
    9941087                                /* perform the search */
    9951088                                SEARCH_codefl( code, searchfl, &dict->dict_cmd_code );
    9961089                        }
    9971090                        break;
    998 
     1091                               
    9991092                case CMD_ANSWER:
    10001093                        {
     
    10021095                                struct dict_object * req = (struct dict_object *) what;
    10031096                                struct dict_object * ans = NULL;
    1004 
    1005                                 CHECK_PARAMS( verify_object(req)
     1097                               
     1098                                CHECK_PARAMS( verify_object(req) 
    10061099                                                && (req->type == DICT_COMMAND)
    10071100                                                && (req->data.cmd.cmd_flag_mask & CMD_FLAG_REQUEST)
    10081101                                                && (req->data.cmd.cmd_flag_val  & CMD_FLAG_REQUEST) );
    1009 
     1102                               
    10101103                                /* The answer is supposed to be the next element in the list, if it exists */
    10111104                                ans = req->list[1].next->o;
     
    10151108                                        goto end;
    10161109                                }
    1017 
     1110                               
    10181111                                /* Now check that the ans element is really the correct one */
    10191112                                if (  (ans->data.cmd.cmd_code != req->data.cmd.cmd_code)
     
    10241117                                        goto end;
    10251118                                }
    1026 
     1119                               
    10271120                                if (result)
    10281121                                        *result = ans;
    10291122                                ret = 0;
    1030                         }
    1031                         break;
    1032 
     1123                        }                                               
     1124                        break;
     1125                       
    10331126                default:
    10341127                        /* Invalid criteria */
     
    10421135{
    10431136        int ret = 0;
    1044 
     1137       
    10451138        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    1046 
     1139       
    10471140        switch (criteria) {
    10481141                case RULE_BY_AVP_AND_PARENT:
     
    10511144                                struct dict_object * avp = NULL;
    10521145                                struct dict_rule_request * _what = (struct dict_rule_request *) what;
    1053 
    1054                                 CHECK_PARAMS( _what
     1146                               
     1147                                CHECK_PARAMS( _what 
    10551148                                                && (parent = _what->rule_parent)
    10561149                                                && (avp    = _what->rule_avp   ) );
    1057 
    1058                                 CHECK_PARAMS( verify_object(parent)
    1059                                                 && ((parent->type == DICT_COMMAND)
     1150                               
     1151                                CHECK_PARAMS( verify_object(parent) 
     1152                                                && ((parent->type == DICT_COMMAND) 
    10601153                                                 || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED))) );
    1061 
     1154                               
    10621155                                CHECK_PARAMS( verify_object(avp) && (avp->type == DICT_AVP) );
    1063 
     1156                               
    10641157                                /* Perform the search */
    10651158                                SEARCH_ruleavpname( avp->data.avp.avp_name, avp->datastr_len, &parent->list[2]);
    1066 
     1159                               
    10671160                        }
    10681161                        break;
    1069 
     1162                       
    10701163                default:
    10711164                        /* Invalid criteria */
     
    10871180{
    10881181        struct dict_vendor_data * vendor = (struct dict_vendor_data *)data;
    1089 
     1182       
    10901183        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name);
    10911184}
     
    10981191{
    10991192        struct dict_type_data * type = ( struct dict_type_data * ) data;
    1100 
    1101         return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"",
    1102                         type_base_name[type->type_base],
     1193       
     1194        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", 
     1195                        type_base_name[type->type_base], 
    11031196                        type->type_name);
    11041197}
     
    11191212                        }
    11201213                        break;
    1121 
     1214               
    11221215                case AVP_TYPE_INTEGER32:
    11231216                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL);
     
    11431236                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL);
    11441237                        break;
    1145 
     1238               
    11461239                default:
    11471240                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL);
     
    11521245{
    11531246        struct dict_avp_data * avp = (struct dict_avp_data * ) data;
    1154         return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"",
    1155                         DUMP_AVPFL_val(avp->avp_flag_val),
    1156                         DUMP_AVPFL_val(avp->avp_flag_mask),
    1157                         type_base_name[avp->avp_basetype],
    1158                         avp->avp_code,
     1247        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", 
     1248                        DUMP_AVPFL_val(avp->avp_flag_val), 
     1249                        DUMP_AVPFL_val(avp->avp_flag_mask), 
     1250                        type_base_name[avp->avp_basetype], 
     1251                        avp->avp_code, 
    11591252                        avp->avp_name );
    11601253}
     
    11621255{
    11631256        struct dict_cmd_data * cmd = (struct dict_cmd_data *) data;
    1164         return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"",
     1257        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", 
    11651258                        DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name);
    11661259}
     
    11691262        struct dict_rule_data * rule = (struct dict_rule_data * )data;
    11701263        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"",
    1171                         rule->rule_position,
    1172                         rule->rule_order,
    1173                         rule->rule_min,
     1264                        rule->rule_position, 
     1265                        rule->rule_order, 
     1266                        rule->rule_min, 
    11741267                        rule->rule_max,
    11751268                        rule->rule_avp->data.avp.avp_name);
     
    11981291{
    11991292        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL);
    1200 
     1293       
    12011294        if (!verify_object(obj)) {
    12021295                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL);
    12031296                return *buf;
    12041297        }
    1205 
    1206         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ",
    1207                                                                 _OBINFO(obj).name,
     1298       
     1299        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", 
     1300                                                                _OBINFO(obj).name, 
    12081301                                                                obj->parent), return NULL);
    1209 
     1302       
    12101303        if (obj->type == DICT_ENUMVAL) {
    12111304                CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL);
     
    12131306                CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL);
    12141307        }
    1215 
     1308       
    12161309        if (parents) {
    12171310                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*sparent:", indent + 1, ""), return NULL);
    12181311                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL);
    12191312        }
    1220 
     1313       
    12211314        if (depth) {
    12221315                int i;
     
    12281321                }
    12291322        }
    1230 
     1323       
    12311324        return *buf;
    12321325}
     
    12351328{
    12361329        FD_DUMP_HANDLE_OFFSET();
    1237 
     1330       
    12381331        CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL);
    1239 
     1332       
    12401333        return *buf;
    12411334}
     
    12451338        int i;
    12461339        struct fd_list * li;
    1247 
     1340       
    12481341        FD_DUMP_HANDLE_OFFSET();
    1249 
     1342               
    12501343        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL);
    1251 
     1344       
    12521345        if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) {
    12531346                return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL");
    12541347        }
    1255 
     1348       
    12561349        CHECK_POSIX_DO(  pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */  );
    1257 
     1350       
    12581351        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): VENDORS / AVP / RULES\n", dict), goto error);
    12591352        CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error);
     
    12621355                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error);
    12631356        }
    1264 
     1357       
    12651358        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): APPLICATIONS\n", dict), goto error);
    12661359        CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error);
     
    12691362                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error);
    12701363        }
    1271 
     1364       
    12721365        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): TYPES / ENUMVAL", dict), goto error);
    12731366        CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error);
    1274 
     1367       
    12751368        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): COMMANDS / RULES", dict), goto error);
    12761369        CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error);
    1277 
     1370       
    12781371        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): statistics", dict), goto error);
    12791372        for (i=1; i<=DICT_TYPE_MAX; i++)
    12801373                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n   %5d: %s",  dict->dict_count[i], dict_obj_info[i].name), goto error);
    1281 
     1374       
    12821375        CHECK_POSIX_DO(  pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */  );
    12831376        return *buf;
    1284 error:
     1377error: 
    12851378        /* Free the rwlock */
    12861379        CHECK_POSIX_DO(  pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */  );
     
    12941387{
    12951388        int i;
    1296 
     1389       
    12971390        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL);
    12981391        for (i = 0; i < value->os.len; i++) {
     
    13431436                case AVP_TYPE_OCTETSTRING:
    13441437                        return &dump_val_os;
    1345 
     1438               
    13461439                case AVP_TYPE_INTEGER32:
    13471440                        return &dump_val_i32;
     
    13611454                case AVP_TYPE_FLOAT64:
    13621455                        return &dump_val_f64;
    1363 
     1456               
    13641457                case AVP_TYPE_GROUPED:
    13651458                        TRACE_DEBUG(FULL, "error: grouped AVP with a value!");
     
    13751468
    13761469/* Formatter for the AVP value dump line */
    1377 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value,
    1378                         dump_val_cb_t def_dump_val_cb,
    1379                         dump_val_cb_t dump_val_cb,
    1380                         enum dict_avp_basetype datatype,
    1381                         char * type_name,
    1382                         char * const_name,
    1383                         int indent,
     1470static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value, 
     1471                        dump_val_cb_t def_dump_val_cb, 
     1472                        dump_val_cb_t dump_val_cb, 
     1473                        enum dict_avp_basetype datatype, 
     1474                        char * type_name, 
     1475                        char * const_name, 
     1476                        int indent, 
    13841477                        int header)
    13851478{
     
    13871480                /* Header for all AVP values dumps: */
    13881481                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL);
    1389 
     1482       
    13901483                /* If the type is provided, write it */
    13911484                if (type_name) {
    13921485                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL);
    13931486                }
    1394 
     1487       
    13951488                /* Always give the base datatype anyway */
    13961489                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL);
     
    14101503                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL);
    14111504        }
    1412 
     1505       
    14131506        /* Done! */
    14141507        return *buf;
     
    14221515        char * type_name = NULL;
    14231516        char * const_name = NULL;
    1424 
     1517       
    14251518        FD_DUMP_HANDLE_OFFSET();
    1426 
     1519       
    14271520        /* Handle invalid parameters */
    14281521        if (!avp_value) {
     
    14351528                return *buf;
    14361529        }
    1437 
     1530       
    14381531        if (! ( verify_object(model) && (model->type == DICT_AVP) )) {
    14391532                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model)"), return NULL);
    14401533                return *buf;
    14411534        }
    1442 
     1535       
    14431536        /* Get the type definition of this AVP */
    14441537        type = model->parent;
     
    14461539                struct dict_enumval_request  request;
    14471540                struct dict_object * enumval = NULL;
    1448 
     1541               
    14491542                type_name = type->data.type.type_name;
    1450 
     1543               
    14511544                /* overwrite the dump function ? */
    14521545                if (type->data.type.type_dump)
    14531546                        dump_val_cb = type->data.type.type_dump;
    1454 
     1547               
    14551548                /* Now check if the AVP value matches a constant */
    14561549                memset(&request, 0, sizeof(request));
     
    14631556                }
    14641557        }
    1465 
     1558       
    14661559        /* And finally, dump the value */
    14671560        CHECK_MALLOC_DO( dump_avp_val(FD_DUMP_STD_PARAMS, avp_value, get_default_dump_val_cb(model->data.avp.avp_basetype), dump_val_cb, model->data.avp.avp_basetype, type_name, const_name, indent, header), return NULL );
     
    14831576{
    14841577        TRACE_ENTRY("%p %p", object, type);
    1485 
     1578       
    14861579        CHECK_PARAMS( type && verify_object(object) );
    1487 
     1580       
    14881581        /* Copy the value and return */
    14891582        *type = object->type;
     
    14941587{
    14951588        TRACE_ENTRY("%p %p", object, dict);
    1496 
     1589       
    14971590        CHECK_PARAMS( dict && verify_object(object) );
    1498 
     1591       
    14991592        /* Copy the value and return */
    15001593        *dict = object->dico;
     
    15071600{
    15081601        TRACE_ENTRY("%p %p", object, val);
    1509 
     1602       
    15101603        CHECK_PARAMS( val && verify_object(object) );
    1511 
     1604       
    15121605        /* Copy the value and return */
    15131606        memcpy(val, &object->data, _OBINFO(object).datasize);;
     
    15231616        struct dict_object * vendor = NULL;
    15241617        struct dict_object * locref = NULL;
    1525 
     1618       
    15261619        TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref);
    1527 
     1620       
    15281621        /* Check parameters */
    15291622        CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) && data  );
    1530 
     1623       
    15311624        /* Check the "parent" parameter */
    15321625        switch (dict_obj_info[type].parent) {
    15331626                case 0: /* parent is forbidden */
    15341627                        CHECK_PARAMS_DO( parent == NULL, goto error_param );
    1535 
     1628               
    15361629                case 1: /* parent is optional */
    15371630                        if (parent == NULL)
    15381631                                break;
    1539 
     1632               
    15401633                case 2: /* parent is mandatory */
    15411634                        CHECK_PARAMS_DO(  verify_object(parent), goto error_param  );
    1542 
     1635                       
    15431636                        if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */
    1544                                 CHECK_PARAMS_DO( (parent->type == DICT_COMMAND )
     1637                                CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) 
    15451638                                                || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param );
    15461639                        } else {
     
    15481641                        }
    15491642        }
    1550 
     1643       
    15511644        /* For AVP object, we must also check that the "vendor" referenced exists */
    15521645        if (type == DICT_AVP) {
    15531646                CHECK_FCT_DO(  fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ),
    15541647                        { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; }  );
    1555 
     1648               
    15561649                /* Also check if a parent is provided, that the type are the same */
    15571650                if (parent) {
     
    15591652                }
    15601653        }
    1561 
     1654       
    15621655        /* For RULE object, we must also check that the "avp" referenced exists */
    15631656        if (type == DICT_RULE) {
     
    15651658                CHECK_PARAMS_DO(  ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param  );
    15661659        }
    1567 
     1660       
    15681661        /* For COMMAND object, check that the 'R' flag is fixed */
    15691662        if (type == DICT_COMMAND) {
     
    15761669                        dupos = 1;
    15771670        }
    1578 
     1671       
    15791672        /* We have to check that the new values are not equal to the sentinels */
    15801673        if (type == DICT_VENDOR) {
     
    15841677                CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param   );
    15851678        }
    1586 
     1679       
    15871680        /* Parameters are valid, create the new object */
    15881681        CHECK_MALLOC(  new = malloc(sizeof(struct dict_object))  );
    1589 
     1682       
    15901683        /* Initialize the data of the new object */
    15911684        init_object(new, type);
     
    15931686        new->dico = dict;
    15941687        new->parent = parent;
    1595 
     1688       
    15961689        /* We will change the dictionary => acquire the write lock */
    15971690        CHECK_POSIX_DO(  ret = pthread_rwlock_wrlock(&dict->dict_lock),  goto error_free  );
    1598 
     1691       
    15991692        /* Now link the object -- this also checks that no object with same keys already exists */
    16001693        switch (type) {
     
    16051698                                goto error_unlock;
    16061699                        break;
    1607 
     1700               
    16081701                case DICT_APPLICATION:
    16091702                        /* An application object is linked in the g_dict_applciations.list[0], by their id */
     
    16121705                                goto error_unlock;
    16131706                        break;
    1614 
     1707               
    16151708                case DICT_TYPE:
    16161709                        /* A type object is linked in g_list_types by its name */
     
    16191712                                goto error_unlock;
    16201713                        break;
    1621 
     1714               
    16221715                case DICT_ENUMVAL:
    16231716                        /* A type_enum object is linked in it's parent 'type' object lists 1 and 2 by its name and values */
     
    16251718                        if (ret)
    16261719                                goto error_unlock;
    1627 
     1720                       
    16281721                        ret = fd_list_insert_ordered ( &parent->list[2], &new->list[1], (int (*)(void*, void *))order_enum_by_val, (void **)&locref );
    1629                         if (ret) {
    1630                                 fd_list_unlink(&new->list[0]);
    1631                                 goto error_unlock;
     1722                        if (ret) { 
     1723                                fd_list_unlink(&new->list[0]); 
     1724                                goto error_unlock; 
    16321725                        }
    16331726                        break;
    1634 
     1727               
    16351728                case DICT_AVP:
    16361729                        /* An avp object is linked in lists 1 and 2 of its vendor, by code and name */
     
    16381731                        if (ret)
    16391732                                goto error_unlock;
    1640 
     1733                       
    16411734                        ret = fd_list_insert_ordered ( &vendor->list[2], &new->list[1], (int (*)(void*, void *))order_avp_by_name, (void **)&locref );
    16421735                        if (ret) {
     
    16451738                        }
    16461739                        break;
    1647 
     1740                       
    16481741                case DICT_COMMAND:
    16491742                        /* A command object is linked in g_list_cmd_name and g_list_cmd_code by its name and code */
     
    16511744                        if (ret)
    16521745                                goto error_unlock;
    1653 
     1746                       
    16541747                        ret = fd_list_insert_ordered ( &dict->dict_cmd_name, &new->list[0], (int (*)(void*, void *))order_cmd_by_name, (void **)&locref );
    16551748                        if (ret) {
     
    16581751                        }
    16591752                        break;
    1660 
     1753               
    16611754                case DICT_RULE:
    16621755                        /* A rule object is linked in list[2] of its parent command or AVP by the name of the AVP it refers */
     
    16651758                                goto error_unlock;
    16661759                        break;
    1667 
     1760                       
    16681761                default:
    16691762                        ASSERT(0);
    16701763        }
    1671 
     1764       
    16721765        /* A new object has been created, increment the global counter */
    16731766        dict->dict_count[type]++;
    1674 
     1767       
    16751768        /* Unlock the dictionary */
    16761769        CHECK_POSIX_DO(  ret = pthread_rwlock_unlock(&dict->dict_lock),  goto error_free  );
    1677 
     1770       
    16781771        /* Save the pointer to the new object */
    16791772        if (ref)
    16801773                *ref = new;
    1681 
     1774       
    16821775        return 0;
    1683 
     1776       
    16841777error_param:
    16851778        ret = EINVAL;
     
    16941787                                TRACE_DEBUG(FULL, "Vendor %s already in dictionary", new->data.vendor.vendor_name);
    16951788                                /* if we are here, it means the two vendors id are identical */
    1696                                 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len,
     1789                                if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, 
    16971790                                                new->data.vendor.vendor_name, new->datastr_len)) {
    16981791                                        TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name);
     
    17001793                                }
    17011794                                /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */
    1702                                 ret = 0;
     1795                                ret = 0; 
    17031796                                break;
    17041797
     
    17061799                                TRACE_DEBUG(FULL, "Application %s already in dictionary", new->data.application.application_name);
    17071800                                /* got same id */
    1708                                 if (fd_os_cmp(locref->data.application.application_name, locref->datastr_len,
     1801                                if (fd_os_cmp(locref->data.application.application_name, locref->datastr_len, 
    17091802                                                new->data.application.application_name, new->datastr_len)) {
    17101803                                        TRACE_DEBUG(FULL, "Conflicting application name");
     
    18441937                char * buf = NULL;
    18451938                size_t len = 0, offset=0;
    1846 
     1939               
    18471940                if (type == DICT_ENUMVAL) {
    18481941                        CHECK_MALLOC( dump_enumval_data ( &buf, &len, &offset, data, parent->data.type.type_base ));
     
    18501943                        CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, &offset, data) );
    18511944                }
    1852 
     1945       
    18531946                TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf);
    1854 
     1947               
    18551948                if (ret == EEXIST) {
    18561949                        offset=0;
     
    18711964        struct dictionary * dict;
    18721965        int ret=0;
    1873 
     1966       
    18741967        /* check params */
    18751968        CHECK_PARAMS( verify_object(obj) && obj->dico);
     
    18781971        /* Lock the dictionary for change */
    18791972        CHECK_POSIX(  pthread_rwlock_wrlock(&dict->dict_lock)  );
    1880 
     1973       
    18811974        /* check the object is not sentinel for another list */
    18821975        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
     
    18911984                }
    18921985        }
    1893 
     1986       
    18941987        /* ok, now destroy the object */
    18951988        if (!ret)
    18961989                destroy_object(obj);
    1897 
     1990       
    18981991        /* Unlock */
    18991992        CHECK_POSIX(  pthread_rwlock_unlock(&dict->dict_lock)  );
    1900 
     1993       
    19011994        return ret;
    19021995}
     
    19061999{
    19072000        int ret = 0;
    1908 
     2001       
    19092002        TRACE_ENTRY("%p %d(%s) %d %p %p %d", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, criteria, what, result, retval);
    1910 
     2003       
    19112004        /* Check param */
    19122005        CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) );
    1913 
     2006       
    19142007        /* Lock the dictionary for reading */
    19152008        CHECK_POSIX(  pthread_rwlock_rdlock(&dict->dict_lock)  );
    1916 
     2009       
    19172010        /* Now call the type-specific search function */
    19182011        ret = dict_obj_info[type].search_fct (dict, criteria, what, result);
    1919 
     2012       
    19202013        /* Unlock */
    19212014        CHECK_POSIX(  pthread_rwlock_unlock(&dict->dict_lock)  );
    1922 
     2015       
    19232016        /* Update the return value as needed */
    19242017        if ((result != NULL) && (*result == NULL))
    19252018                ret = retval;
    1926 
     2019       
    19272020        return ret;
    19282021}
     
    19372030  }
    19382031
    1939 The following criteria are allowed, with corresponding parent.
     2032The following criteria are allowed, with corresponding parent. 
    19402033The parent is either struct dictionary * or struct dict_object *
    1941 
     2034               
    19422035VENDOR_BY_ID : (parent = dictionary) returns list of vendors ordered by ID
    19432036APPLICATION_BY_ID : (parent = dictionary) returns list of applications ordered by ID
    1944   ** for these two lists, the Vendor with id 0 and applciation with id 0 are excluded.
     2037  ** for these two lists, the Vendor with id 0 and applciation with id 0 are excluded. 
    19452038     You must resolve them separatly with dict_search.
    1946 
     2039               
    19472040TYPE_BY_NAME : (parent = dictionary) returns list of types ordered by name (osstring order)
    19482041ENUMVAL_BY_NAME : (parent = type object) return list of constants for this type ordered by name (osstring order)
     
    19602053        struct dictionary * dict = parent;
    19612054        struct dict_object * obj_parent = parent;
    1962 
     2055       
    19632056        TRACE_ENTRY("%i %p %p", criteria, parent, sentinel);
    1964 
     2057       
    19652058        CHECK_PARAMS(sentinel && parent);
    1966 
     2059       
    19672060        switch(criteria) {
    19682061                case VENDOR_BY_ID: /* parent must be the dictionary */
     
    19702063                        *sentinel = &dict->dict_vendors.list[0];
    19712064                        break;
    1972 
     2065                       
    19732066                case APPLICATION_BY_ID: /* parent must be the dictionary */
    19742067                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    19752068                        *sentinel = &dict->dict_applications.list[0];
    19762069                        break;
    1977 
     2070                       
    19782071                case TYPE_BY_NAME: /* parent must be the dictionary */
    19792072                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    19802073                        *sentinel = &dict->dict_types;
    19812074                        break;
    1982 
     2075                       
    19832076                case ENUMVAL_BY_NAME: /* parent must be a type object */
    19842077                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE));
    19852078                        *sentinel = &obj_parent->list[1];
    19862079                        break;
    1987 
     2080                       
    19882081                case ENUMVAL_BY_VALUE: /* parent must be a type object */
    19892082                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE));
    19902083                        *sentinel = &obj_parent->list[2];
    19912084                        break;
    1992 
     2085                       
    19932086                case AVP_BY_NAME: /* parent must be a VENDOR object */
    19942087                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR));
    19952088                        *sentinel = &obj_parent->list[2];
    19962089                        break;
    1997 
     2090                       
    19982091                case AVP_BY_CODE: /* parent must be a VENDOR object */
    19992092                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR));
    20002093                        *sentinel = &obj_parent->list[1];
    20012094                        break;
    2002 
     2095                       
    20032096                case CMD_BY_NAME: /* parent must be the dictionary */
    20042097                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    20052098                        *sentinel = &dict->dict_cmd_name;
    20062099                        break;
    2007 
     2100                       
    20082101                case CMD_BY_CODE_R: /* parent must be the dictionary */
    20092102                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    20102103                        *sentinel = &dict->dict_cmd_code;
    20112104                        break;
    2012 
     2105                       
    20132106                case RULE_BY_AVP_AND_PARENT: /* parent must be command or grouped AVP */
    20142107                        CHECK_PARAMS(verify_object(obj_parent));
    20152108                        CHECK_PARAMS(   (obj_parent->type == DICT_COMMAND) ||
    2016                                         ((obj_parent->type == DICT_AVP)
     2109                                        ((obj_parent->type == DICT_AVP) 
    20172110                                          && (obj_parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) );
    20182111                        *sentinel = &obj_parent->list[2];
    20192112                        break;
    2020 
     2113                       
    20212114                default:
    20222115                        CHECK_PARAMS(0);
    20232116        }
    2024 
     2117       
    20252118        return 0;
    20262119}
     
    20382131{
    20392132        struct dictionary * new = NULL;
    2040 
     2133       
    20412134        TRACE_ENTRY("%p", dict);
    2042 
     2135       
    20432136        /* Sanity checks */
    20442137        ASSERT( (sizeof(type_base_name) / sizeof(type_base_name[0])) == (AVP_TYPE_MAX + 1) );
    20452138        ASSERT( (sizeof(dict_obj_info)  / sizeof(dict_obj_info[0]))  == (DICT_TYPE_MAX + 1) );
    20462139        CHECK_PARAMS(dict);
    2047 
     2140       
    20482141        /* Allocate the memory for the dictionary */
    20492142        CHECK_MALLOC( new = malloc(sizeof(struct dictionary)) );
    20502143        memset(new, 0, sizeof(struct dictionary));
    2051 
     2144       
    20522145        new->dict_eyec = DICT_EYECATCHER;
    2053 
     2146       
    20542147        /* Initialize the lock for the dictionary */
    20552148        CHECK_POSIX(  pthread_rwlock_init(&new->dict_lock, NULL)  );
    2056 
     2149       
    20572150        /* Initialize the sentinel for vendors and AVP lists */
    20582151        init_object( &new->dict_vendors, DICT_VENDOR );
     
    20622155        /* new->dict_vendors.list[0].o = NULL; *//* overwrite since element is also sentinel for this list. */
    20632156        new->dict_vendors.dico = new;
    2064 
     2157       
    20652158        /* Initialize the sentinel for applications */
    20662159        init_object( &new->dict_applications, DICT_APPLICATION );
     
    20702163        /* new->dict_applications.list[0].o = NULL; *//* overwrite since since element is also sentinel for this list. */
    20712164        new->dict_applications.dico = new;
    2072 
     2165                       
    20732166        /* Initialize the sentinel for types */
    20742167        fd_list_init ( &new->dict_types, NULL );
    2075 
     2168       
    20762169        /* Initialize the sentinels for commands */
    20772170        fd_list_init ( &new->dict_cmd_name, NULL );
    20782171        fd_list_init ( &new->dict_cmd_code, NULL );
    2079 
     2172       
    20802173        /* Initialize the error command object */
    20812174        init_object( &new->dict_cmd_error, DICT_COMMAND );
     
    20862179        new->dict_cmd_error.data.cmd.cmd_flag_val =CMD_FLAG_ERROR;
    20872180        new->dict_cmd_error.dico = new;
    2088 
     2181       
    20892182        *dict = new;
    2090 
     2183       
    20912184        /* Done */
    20922185        return 0;
     
    20972190{
    20982191        int i;
    2099 
     2192       
    21002193        TRACE_ENTRY("");
    21012194        CHECK_PARAMS( dict && *dict && ((*dict)->dict_eyec == DICT_EYECATCHER) );
    2102 
     2195       
    21032196        /* Acquire the write lock to make sure no other operation is ongoing */
    21042197        CHECK_POSIX(  pthread_rwlock_wrlock(&(*dict)->dict_lock)  );
    2105 
     2198       
    21062199        /* Empty all the lists, free the elements */
    21072200        destroy_list ( &(*dict)->dict_cmd_error.list[2] );
     
    21132206                destroy_list ( &(*dict)->dict_vendors.list[i] );
    21142207        }
    2115 
     2208       
    21162209        /* Dictionary is empty, now destroy the lock */
    21172210        CHECK_POSIX(  pthread_rwlock_unlock(&(*dict)->dict_lock)  );
    21182211        CHECK_POSIX(  pthread_rwlock_destroy(&(*dict)->dict_lock)  );
    2119 
     2212       
    21202213        free(*dict);
    21212214        *dict = NULL;
    2122 
     2215       
    21232216        return 0;
    21242217}
     
    21372230        int ret = 0;
    21382231        struct fd_list * li;
    2139 
     2232       
    21402233        TRACE_ENTRY("%p %p %p", parent, data, cb);
    2141 
     2234       
    21422235        /* Check parameters */
    21432236        CHECK_PARAMS(  verify_object(parent)  );
    2144         CHECK_PARAMS(  (parent->type == DICT_COMMAND)
     2237        CHECK_PARAMS(  (parent->type == DICT_COMMAND) 
    21452238                        || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) );
    2146         TRACE_DEBUG (FULL, "Iterating on rules of %s: '%s'.",
    2147                         _OBINFO(parent).name,
    2148                         parent->type == DICT_COMMAND ?
     2239        TRACE_DEBUG (FULL, "Iterating on rules of %s: '%s'.", 
     2240                        _OBINFO(parent).name, 
     2241                        parent->type == DICT_COMMAND ? 
    21492242                                  parent->data.cmd.cmd_name
    21502243                                : parent->data.avp.avp_name);
    2151 
     2244       
    21522245        /* Acquire the read lock  */
    21532246        CHECK_POSIX(  pthread_rwlock_rdlock(&parent->dico->dict_lock)  );
    2154 
     2247       
    21552248        /* go through the list and call the cb on each rule data */
    21562249        for (li = &(parent->list[2]); li->next != &(parent->list[2]); li = li->next) {
     
    21592252                        break;
    21602253        }
    2161 
     2254               
    21622255        /* Release the lock */
    21632256        CHECK_POSIX(  pthread_rwlock_unlock(&parent->dico->dict_lock)  );
    2164 
     2257       
    21652258        return ret;
    21662259}
     
    21722265        int i = 0;
    21732266        struct fd_list * li;
    2174 
     2267       
    21752268        TRACE_ENTRY();
    2176 
     2269       
    21772270        /* Acquire the read lock */
    21782271        CHECK_POSIX_DO(  pthread_rwlock_rdlock(&dict->dict_lock), return NULL  );
    2179 
     2272       
    21802273        /* Allocate an array to contain all the elements */
    21812274        CHECK_MALLOC_DO( ret = calloc( dict->dict_count[DICT_VENDOR] + 1, sizeof(uint32_t) ), goto out );
    2182 
     2275       
    21832276        /* Copy the vendors IDs */
    21842277        for (li = dict->dict_vendors.list[0].next; li != &(dict->dict_vendors.list[0]); li = li->next) {
     
    21872280                ASSERT( i <= dict->dict_count[DICT_VENDOR] );
    21882281        }
    2189 out:
     2282out:   
    21902283        /* Release the lock */
    21912284        CHECK_POSIX_DO(  pthread_rwlock_unlock(&dict->dict_lock), return NULL  );
    2192 
     2285       
    21932286        return ret;
    21942287}
Note: See TracChangeset for help on using the changeset viewer.