Navigation


Changeset 1451:6c3485887511 in freeDiameter for libfdproto


Ignore:
Timestamp:
Feb 27, 2020, 11:40:25 PM (4 years ago)
Author:
Thomas Klausner <tk@giga.or.at>
Branch:
default
Phase:
public
Message:

Move some structures to a header file for use by dbg_dict_dump_json.

Remove trailing whitespace.

Location:
libfdproto
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/dictionary.c

    r1444 r1451  
    3535
    3636#include "fdproto-internal.h"
     37#include "dictionary-internal.h"
    3738#include <inttypes.h>
    3839
     
    4950        };
    5051
    51 /* The number of lists in an object */
    52 #define NB_LISTS_PER_OBJ        3
    53 
    5452/* Some eye catchers definitions */
    5553#define OBJECT_EYECATCHER       (0x0b13c7)
    5654#define DICT_EYECATCHER         (0x00d1c7)
    57 
    58 /* Definition of the dictionary objects */
    59 struct 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 */
    133 struct 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 };
    14855
    14956/* Forward declarations of dump functions */
     
    17885} dict_obj_info[] = { { 0, "(error)", 0, 0, 0, 0, NULL, NULL, {0, 0, 0} }
    17986
    180         /* type                  name           datasize                          parent        parenttype 
     87        /* type                  name           datasize                          parent        parenttype
    18188                        eyecatcher              dump_data               search_fct,             haslist[]       */
    18289
    18390        ,{ DICT_VENDOR,         "VENDOR",       sizeof(struct dict_vendor_data),        0,      0,
    18491                        OBJECT_EYECATCHER + 1,  dump_vendor_data,       search_vendor,          { 1, 0, 0 } }
    185        
     92
    18693        ,{ DICT_APPLICATION,    "APPLICATION",  sizeof(struct dict_application_data),   1,      DICT_VENDOR,
    18794                        OBJECT_EYECATCHER + 2,  dump_application_data,  search_application,     { 1, 0, 0 } }
    188        
     95
    18996        ,{ DICT_TYPE,           "TYPE",         sizeof(struct dict_type_data),          1,      DICT_APPLICATION,
    19097                        OBJECT_EYECATCHER + 3,  dump_type_data,         search_type,            { 1, 0, 0 } }
    191        
     98
    19299        ,{ DICT_ENUMVAL,        "ENUMVAL",      sizeof(struct dict_enumval_data),       2,      DICT_TYPE,
    193100                        OBJECT_EYECATCHER + 4,  NULL,                   search_enumval, { 1, 1, 0 } }
    194        
     101
    195102        ,{ DICT_AVP,            "AVP",          sizeof(struct dict_avp_data),           1,      DICT_TYPE,
    196103                        OBJECT_EYECATCHER + 5,  dump_avp_data,          search_avp,             { 1, 1, 0 } }
    197        
     104
    198105        ,{ DICT_COMMAND,        "COMMAND",      sizeof(struct dict_cmd_data),           1,      DICT_APPLICATION,
    199106                        OBJECT_EYECATCHER + 6,  dump_command_data,      search_cmd,             { 1, 1, 0 } }
    200        
     107
    201108        ,{ DICT_RULE,           "RULE",         sizeof(struct dict_rule_data),          2,      -1 /* special case: grouped avp or command */,
    202109                        OBJECT_EYECATCHER + 7,  dump_rule_data,         search_rule,            { 1, 0, 0 } }
    203        
     110
    204111};
    205        
     112
    206113/* Macro to verify a "type" value */
    207114#define CHECK_TYPE( type ) ( ((type) > 0) && ((type) <= DICT_TYPE_MAX) )
     
    231138        str = os0dup( str, *(plen));            \
    232139}
    233        
     140
    234141/* Initialize an object */
    235142static void init_object( struct dict_object * obj, enum dict_object_type type )
    236143{
    237144        int i;
    238        
     145
    239146        TRACE_ENTRY("%p %d", obj, type);
    240        
     147
    241148        /* Clean the object first */
    242149        memset ( obj, 0, sizeof(struct dict_object));
    243        
     150
    244151        CHECK_PARAMS_DO(  CHECK_TYPE(type),  return  );
    245152
     
    249156
    250157        /* We don't initialize the data nor the parent here */
    251        
     158
    252159        /* Now init the lists */
    253160        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
    254                 if (_OBINFO(obj).haslist[i] != 0) 
     161                if (_OBINFO(obj).haslist[i] != 0)
    255162                        fd_list_init(&obj->list[i], obj);
    256163                else
    257164                        fd_list_init(&obj->list[i], NULL);
    258165        }
    259        
     166
    260167        fd_list_init(&obj->disp_cbs, NULL);
    261168}
     
    266173        TRACE_ENTRY("%p %p %d", dest, source, type);
    267174        CHECK_PARAMS( dest && source && CHECK_TYPE(type) );
    268        
    269         /* Generic: copy the full data structure */     
     175
     176        /* Generic: copy the full data structure */
    270177        memcpy( &dest->data, source, dict_obj_info[type].datasize );
    271        
     178
    272179        /* Then strings must be duplicated, not copied */
    273180        /* This function might be simplified by always defining the "name" field as the first field of the structures, but... it's error-prone */
     
    276183                        DUP_string_len( dest->data.vendor.vendor_name, &dest->datastr_len );
    277184                        break;
    278                
     185
    279186                case DICT_APPLICATION:
    280187                        DUP_string_len( dest->data.application.application_name, &dest->datastr_len );
    281188                        break;
    282                        
     189
    283190                case DICT_TYPE:
    284191                        DUP_string_len( dest->data.type.type_name, &dest->datastr_len );
    285192                        break;
    286                        
     193
    287194                case DICT_ENUMVAL:
    288195                        DUP_string_len( dest->data.enumval.enum_name, &dest->datastr_len );
    289196                        if (dupos) {
    290197                                // we also need to duplicate the octetstring constant value since it is a pointer.
    291                                 dest->data.enumval.enum_value.os.data = os0dup( 
    292                                                 ((struct dict_enumval_data *)source)->enum_value.os.data, 
     198                                dest->data.enumval.enum_value.os.data = os0dup(
     199                                                ((struct dict_enumval_data *)source)->enum_value.os.data,
    293200                                                ((struct dict_enumval_data *)source)->enum_value.os.len
    294201                                        );
     
    299206                        DUP_string_len( dest->data.avp.avp_name, &dest->datastr_len );
    300207                        break;
    301                        
     208
    302209                case DICT_COMMAND:
    303210                        DUP_string_len( dest->data.cmd.cmd_name, &dest->datastr_len );
    304211                        break;
    305                
     212
    306213                default:
    307214                        /* Nothing to do for RULES */
    308215                        ;
    309216        }
    310        
     217
    311218        return 0;
    312219}
     
    316223{
    317224        TRACE_ENTRY("%p", obj);
    318        
     225
    319226        CHECK_PARAMS_DO(  obj
    320227                        && (obj->objeyec == OBJECT_EYECATCHER)
     
    334241                        return 0;
    335242                }  );
    336        
     243
    337244        /* The object is probably valid. */
    338245        return 1;
     
    343250{
    344251        /* TRACE_ENTRY("%p", obj); */
    345        
     252
    346253        switch (obj->type) {
    347254                case DICT_VENDOR:
    348255                        free( obj->data.vendor.vendor_name );
    349256                        break;
    350                
     257
    351258                case DICT_APPLICATION:
    352259                        free( obj->data.application.application_name );
    353260                        break;
    354                        
     261
    355262                case DICT_TYPE:
    356263                        free( obj->data.type.type_name );
    357264                        break;
    358                        
     265
    359266                case DICT_ENUMVAL:
    360267                        free( obj->data.enumval.enum_name );
     
    364271                        free( obj->data.avp.avp_name );
    365272                        break;
    366                        
     273
    367274                case DICT_COMMAND:
    368275                        free( obj->data.cmd.cmd_name );
    369276                        break;
    370                
     277
    371278                default:
    372279                        /* nothing to do */
     
    379286
    380287/* Destroy all objects in a list - the lock must be held */
    381 static void destroy_list(struct fd_list * head) 
     288static void destroy_list(struct fd_list * head)
    382289{
    383290        /* TRACE_ENTRY("%p", head); */
    384        
     291
    385292        /* loop in the list */
    386293        while (!FD_IS_LIST_EMPTY(head))
     
    390297        }
    391298}
    392        
     299
    393300/* Free an object and its sublists */
    394301static void destroy_object(struct dict_object * obj)
    395302{
    396303        int i;
    397        
     304
    398305        /* TRACE_ENTRY("%p", obj); */
    399        
     306
    400307        /* Update global count */
    401         if (obj->dico) 
     308        if (obj->dico)
    402309                obj->dico->dict_count[obj->type]--;
    403        
     310
    404311        /* Mark the object as invalid */
    405312        obj->objeyec = 0xdead;
    406        
     313
    407314        /* First, destroy the data associated to the object */
    408315        destroy_object_data(obj);
    409        
     316
    410317        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
    411318                if (_OBINFO(obj).haslist[i])
     
    416323                        destroy_list( &obj->list[i] );
    417324        }
    418        
     325
    419326        /* Unlink all elements from the dispatch list; they will be freed when callback is unregistered */
    420327        CHECK_POSIX_DO( pthread_rwlock_wrlock(&fd_disp_lock), /* continue */ );
     
    423330        }
    424331        CHECK_POSIX_DO( pthread_rwlock_unlock(&fd_disp_lock), /* continue */ );
    425        
     332
    426333        /* Last, destroy the object */
    427334        free(obj);
     
    438345/* Compare two values */
    439346#define ORDER_scalar( i1, i2 ) \
    440         ((i1 < i2 ) ? -1 : ( i1 > i2 ? 1 : 0 )) 
     347        ((i1 < i2 ) ? -1 : ( i1 > i2 ? 1 : 0 ))
    441348
    442349
     
    445352{
    446353        TRACE_ENTRY("%p %p", o1, o2);
    447        
     354
    448355        return ORDER_scalar( o1->data.vendor.vendor_id, o2->data.vendor.vendor_id );
    449356}
     
    453360{
    454361        TRACE_ENTRY("%p %p", o1, o2);
    455        
     362
    456363        return ORDER_scalar( o1->data.application.application_id, o2->data.application.application_id );
    457364}
     
    461368{
    462369        TRACE_ENTRY("%p %p", o1, o2);
    463        
     370
    464371        return fd_os_cmp( o1->data.type.type_name, o1->datastr_len, o2->data.type.type_name, o2->datastr_len );
    465372}
     
    469376{
    470377        TRACE_ENTRY("%p %p", o1, o2);
    471        
     378
    472379        return fd_os_cmp( o1->data.enumval.enum_name, o1->datastr_len, o2->data.enumval.enum_name, o2->datastr_len );
    473380}
     
    477384{
    478385        TRACE_ENTRY("%p %p", o1, o2);
    479        
     386
    480387        /* The comparison function depends on the type of data */
    481388        switch ( o1->parent->data.type.type_base ) {
    482389                case AVP_TYPE_OCTETSTRING:
    483                         return fd_os_cmp( o1->data.enumval.enum_value.os.data, o1->data.enumval.enum_value.os.len, 
     390                        return fd_os_cmp( o1->data.enumval.enum_value.os.data, o1->data.enumval.enum_value.os.len,
    484391                                          o2->data.enumval.enum_value.os.data, o2->data.enumval.enum_value.os.len);
    485                
     392
    486393                case AVP_TYPE_INTEGER32:
    487394                        return ORDER_scalar( o1->data.enumval.enum_value.i32, o2->data.enumval.enum_value.i32 );
     
    513420{
    514421        TRACE_ENTRY("%p %p", o1, o2);
    515        
     422
    516423        return ORDER_scalar( o1->data.avp.avp_code, o2->data.avp.avp_code );
    517424}
     
    521428{
    522429        TRACE_ENTRY("%p %p", o1, o2);
    523        
     430
    524431        return fd_os_cmp( o1->data.avp.avp_name, o1->datastr_len, o2->data.avp.avp_name, o2->datastr_len );
    525432}
     
    529436{
    530437        TRACE_ENTRY("%p %p", o1, o2);
    531        
     438
    532439        return fd_os_cmp( o1->data.cmd.cmd_name, o1->datastr_len, o2->data.cmd.cmd_name, o2->datastr_len );
    533440}
     
    538445        uint8_t fl1, fl2;
    539446        int cmp = 0;
    540        
     447
    541448        TRACE_ENTRY("%p %p", o1, o2);
    542        
     449
    543450        cmp = ORDER_scalar( o1->data.cmd.cmd_code, o2->data.cmd.cmd_code );
    544         if (cmp) 
     451        if (cmp)
    545452                return cmp;
    546        
     453
    547454        /* Same command code, we must compare the value of the 'R' flag */
    548455        fl1 = o1->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST;
    549456        fl2 = o2->data.cmd.cmd_flag_val & CMD_FLAG_REQUEST;
    550        
     457
    551458        /* We want requests first, so we reverse the operators here */
    552459        return ORDER_scalar(fl2, fl1);
    553                
     460
    554461}
    555462
     
    558465{
    559466        TRACE_ENTRY("%p %p", o1, o2);
    560        
    561         return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor) 
     467
     468        return ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_vendor, o2->data.rule.rule_avp->data.avp.avp_vendor)
    562469                ?: ORDER_scalar(o1->data.rule.rule_avp->data.avp.avp_code, o2->data.rule.rule_avp->data.avp.avp_code) ;
    563470}
     
    745652        int ret = 0;
    746653        vendor_id_t id;
    747        
     654
    748655        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    749        
     656
    750657        switch (criteria) {
    751658                case VENDOR_BY_ID:
     
    753660                        SEARCH_scalar( id, &dict->dict_vendors.list[0], vendor.vendor_id, 1, &dict->dict_vendors );
    754661                        break;
    755                                
     662
    756663                case VENDOR_BY_NAME:
    757664                        /* "what" is a vendor name */
    758665                        SEARCH_os0( what, &dict->dict_vendors.list[0], vendor.vendor_name, 0);
    759666                        break;
    760                        
     667
    761668                case VENDOR_OF_APPLICATION:
    762669                        /* "what" should be an application object */
    763670                        SEARCH_childs_parent( DICT_APPLICATION, &dict->dict_vendors );
    764671                        break;
    765                
     672
    766673                case VENDOR_OF_AVP:
    767674                        /* "what" should be an avp object */
    768675                        SEARCH_sentinel( DICT_AVP, 0, 1 );
    769676                        break;
    770                
     677
    771678                default:
    772679                        /* Invalid criteria */
     
    781688        int ret = 0;
    782689        application_id_t id;
    783        
     690
    784691        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    785        
     692
    786693        switch (criteria) {
    787694                case APPLICATION_BY_ID:
     
    790697                        SEARCH_scalar( id, &dict->dict_applications.list[0],  application.application_id, 1, &dict->dict_applications );
    791698                        break;
    792                                
     699
    793700                case APPLICATION_BY_NAME:
    794701                        /* "what" is an application name */
    795702                        SEARCH_os0( what, &dict->dict_applications.list[0], application.application_name, 0);
    796703                        break;
    797                        
     704
    798705                case APPLICATION_OF_TYPE:
    799706                        /* "what" should be a type object */
    800707                        SEARCH_childs_parent( DICT_TYPE, &dict->dict_applications );
    801708                        break;
    802                
     709
    803710                case APPLICATION_OF_COMMAND:
    804711                        /* "what" should be a command object */
    805712                        SEARCH_childs_parent( DICT_COMMAND, &dict->dict_applications );
    806713                        break;
    807                
     714
    808715                default:
    809716                        /* Invalid criteria */
     
    817724{
    818725        int ret = 0;
    819        
     726
    820727        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    821        
     728
    822729        switch (criteria) {
    823730                case TYPE_BY_NAME:
     
    825732                        SEARCH_os0( what, &dict->dict_types, type.type_name, 1);
    826733                        break;
    827                        
     734
    828735                case TYPE_OF_ENUMVAL:
    829736                        /* "what" should be a type_enum object */
    830737                        SEARCH_childs_parent( DICT_ENUMVAL, NULL );
    831738                        break;
    832                
     739
    833740                case TYPE_OF_AVP:
    834741                        /* "what" should be an avp object */
    835742                        SEARCH_childs_parent( DICT_AVP, NULL );
    836743                        break;
    837                
    838                                
     744
     745
    839746                default:
    840747                        /* Invalid criteria */
     
    848755{
    849756        int ret = 0;
    850        
     757
    851758        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    852        
     759
    853760        switch (criteria) {
    854761                case ENUMVAL_BY_STRUCT:
     
    856763                                struct dict_object * parent = NULL;
    857764                                struct dict_enumval_request * _what = (struct dict_enumval_request *) what;
    858                                
     765
    859766                                CHECK_PARAMS(  _what  &&  ( _what->type_obj || _what->type_name )  );
    860                                
     767
    861768                                if (_what->type_obj != NULL) {
    862769                                        parent = _what->type_obj;
     
    867774                                                        CHECK_PARAMS( 0 ) );
    868775                                }
    869                                
     776
    870777                                /* From here the "parent" object is valid */
    871                                
     778
    872779                                if ( _what->search.enum_name != NULL ) {
    873780                                        /* We are looking for this string */
     
    877784                                        switch (parent->data.type.type_base) {
    878785                                                case AVP_TYPE_OCTETSTRING:
    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 , 
     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 ,
    883790                                                                         1 );
    884791                                                        break;
     
    891798                                                                        (struct dict_object *)NULL);
    892799                                                        break;
    893                                                        
     800
    894801                                                case AVP_TYPE_INTEGER64:
    895802                                                        SEARCH_scalar(  _what->search.enum_value.i64,
     
    899806                                                                        (struct dict_object *)NULL);
    900807                                                        break;
    901                                                        
     808
    902809                                                case AVP_TYPE_UNSIGNED32:
    903810                                                        SEARCH_scalar(  _what->search.enum_value.u32,
     
    907814                                                                        (struct dict_object *)NULL);
    908815                                                        break;
    909                                                        
     816
    910817                                                case AVP_TYPE_UNSIGNED64:
    911818                                                        SEARCH_scalar(  _what->search.enum_value.u64,
     
    915822                                                                        (struct dict_object *)NULL);
    916823                                                        break;
    917                                                        
     824
    918825                                                case AVP_TYPE_FLOAT32:
    919826                                                        SEARCH_scalar(  _what->search.enum_value.f32,
     
    923830                                                                        (struct dict_object *)NULL);
    924831                                                        break;
    925                                                        
     832
    926833                                                case AVP_TYPE_FLOAT64:
    927834                                                        SEARCH_scalar(  _what->search.enum_value.f64,
     
    931838                                                                        (struct dict_object *)NULL);
    932839                                                        break;
    933                                                        
     840
    934841                                                default:
    935842                                                        /* Invalid parent type basetype */
     
    937844                                        }
    938845                                }
    939                                
     846
    940847                        }
    941848                        break;
    942                
    943                                
     849
     850
    944851                default:
    945852                        /* Invalid criteria */
     
    953860{
    954861        int ret = 0;
    955        
     862
    956863        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    957        
     864
    958865        switch (criteria) {
    959866                case AVP_BY_CODE:
     
    965872                        }
    966873                        break;
    967                                
     874
    968875                case AVP_BY_NAME:
    969876                        /* "what" is the AVP name, vendor 0 */
    970877                        SEARCH_os0( what, &dict->dict_vendors.list[2], avp.avp_name, 1);
    971878                        break;
    972                        
     879
    973880                case AVP_BY_CODE_AND_VENDOR:
    974881                case AVP_BY_NAME_AND_VENDOR:
     
    976883                                struct dict_avp_request * _what = (struct dict_avp_request *) what;
    977884                                struct dict_object * vendor = NULL;
    978                                
     885
    979886                                CHECK_PARAMS( (criteria != AVP_BY_NAME_AND_VENDOR) || _what->avp_name  );
    980                                
     887
    981888                                /* Now look for the vendor first */
    982889                                CHECK_FCT( search_vendor( dict, VENDOR_BY_ID, &_what->avp_vendor, &vendor ) );
     
    988895                                        goto end;
    989896                                }
    990                                
     897
    991898                                /* We now have our vendor = head of the appropriate avp list */
    992899                                if (criteria == AVP_BY_NAME_AND_VENDOR) {
     
    998905                        }
    999906                        break;
    1000                
     907
    1001908                case AVP_BY_STRUCT:
    1002909                        {
    1003910                                struct dict_avp_request_ex * _what = (struct dict_avp_request_ex *) what;
    1004911                                struct dict_object * vendor = NULL;
    1005                                
     912
    1006913                                CHECK_PARAMS( _what->avp_vendor.vendor || _what->avp_vendor.vendor_id || _what->avp_vendor.vendor_name );
    1007914                                CHECK_PARAMS( _what->avp_data.avp_code || _what->avp_data.avp_name );
    1008                                
     915
    1009916                                /* Now look for the vendor first */
    1010917                                if (_what->avp_vendor.vendor) {
     
    1017924                                        CHECK_FCT( search_vendor( dict, VENDOR_BY_NAME, _what->avp_vendor.vendor_name, &vendor ) );
    1018925                                }
    1019                                
     926
    1020927                                if (vendor == NULL) {
    1021928                                        if (result)
     
    1025932                                        goto end;
    1026933                                }
    1027                                
     934
    1028935                                /* We now have our vendor = head of the appropriate avp list */
    1029936                                if (_what->avp_data.avp_code) {
     
    1035942                        }
    1036943                        break;
    1037                
     944
    1038945                case AVP_BY_NAME_ALL_VENDORS:
    1039946                        {
    1040947                                struct fd_list * li;
    1041948                                size_t wl = strlen((char *)what);
    1042                                
     949
    1043950                                /* First, search for vendor 0 */
    1044951                                SEARCH_os0_l( what, wl, &dict->dict_vendors.list[2], avp.avp_name, 1);
    1045                                
     952
    1046953                                /* If not found, loop for all vendors, until found */
    1047954                                for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) {
     
    1050957                        }
    1051958                        break;
    1052                
     959
    1053960                default:
    1054961                        /* Invalid criteria */
     
    1062969{
    1063970        int ret = 0;
    1064        
     971
    1065972        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    1066        
     973
    1067974        switch (criteria) {
    1068975                case CMD_BY_NAME:
     
    1070977                        SEARCH_os0( what, &dict->dict_cmd_name, cmd.cmd_name, 1);
    1071978                        break;
    1072                        
     979
    1073980                case CMD_BY_CODE_R:
    1074981                case CMD_BY_CODE_A:
     
    1076983                                command_code_t code;
    1077984                                uint8_t searchfl = 0;
    1078                                
     985
    1079986                                /* The command code that we are searching */
    1080987                                code = *(command_code_t *) what;
    1081                                
     988
    1082989                                /* The flag (request or answer) of the command we are searching */
    1083990                                if (criteria == CMD_BY_CODE_R) {
    1084991                                        searchfl = CMD_FLAG_REQUEST;
    1085992                                }
    1086                                
     993
    1087994                                /* perform the search */
    1088995                                SEARCH_codefl( code, searchfl, &dict->dict_cmd_code );
    1089996                        }
    1090997                        break;
    1091                                
     998
    1092999                case CMD_ANSWER:
    10931000                        {
     
    10951002                                struct dict_object * req = (struct dict_object *) what;
    10961003                                struct dict_object * ans = NULL;
    1097                                
    1098                                 CHECK_PARAMS( verify_object(req) 
     1004
     1005                                CHECK_PARAMS( verify_object(req)
    10991006                                                && (req->type == DICT_COMMAND)
    11001007                                                && (req->data.cmd.cmd_flag_mask & CMD_FLAG_REQUEST)
    11011008                                                && (req->data.cmd.cmd_flag_val  & CMD_FLAG_REQUEST) );
    1102                                
     1009
    11031010                                /* The answer is supposed to be the next element in the list, if it exists */
    11041011                                ans = req->list[1].next->o;
     
    11081015                                        goto end;
    11091016                                }
    1110                                
     1017
    11111018                                /* Now check that the ans element is really the correct one */
    11121019                                if (  (ans->data.cmd.cmd_code != req->data.cmd.cmd_code)
     
    11171024                                        goto end;
    11181025                                }
    1119                                
     1026
    11201027                                if (result)
    11211028                                        *result = ans;
    11221029                                ret = 0;
    1123                         }                                               
    1124                         break;
    1125                        
     1030                        }
     1031                        break;
     1032
    11261033                default:
    11271034                        /* Invalid criteria */
     
    11351042{
    11361043        int ret = 0;
    1137        
     1044
    11381045        TRACE_ENTRY("%p %d %p %p", dict, criteria, what, result);
    1139        
     1046
    11401047        switch (criteria) {
    11411048                case RULE_BY_AVP_AND_PARENT:
     
    11441051                                struct dict_object * avp = NULL;
    11451052                                struct dict_rule_request * _what = (struct dict_rule_request *) what;
    1146                                
    1147                                 CHECK_PARAMS( _what 
     1053
     1054                                CHECK_PARAMS( _what
    11481055                                                && (parent = _what->rule_parent)
    11491056                                                && (avp    = _what->rule_avp   ) );
    1150                                
    1151                                 CHECK_PARAMS( verify_object(parent) 
    1152                                                 && ((parent->type == DICT_COMMAND) 
     1057
     1058                                CHECK_PARAMS( verify_object(parent)
     1059                                                && ((parent->type == DICT_COMMAND)
    11531060                                                 || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED))) );
    1154                                
     1061
    11551062                                CHECK_PARAMS( verify_object(avp) && (avp->type == DICT_AVP) );
    1156                                
     1063
    11571064                                /* Perform the search */
    11581065                                SEARCH_ruleavpname( avp->data.avp.avp_name, avp->datastr_len, &parent->list[2]);
    1159                                
     1066
    11601067                        }
    11611068                        break;
    1162                        
     1069
    11631070                default:
    11641071                        /* Invalid criteria */
     
    11801087{
    11811088        struct dict_vendor_data * vendor = (struct dict_vendor_data *)data;
    1182        
     1089
    11831090        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name);
    11841091}
     
    11911098{
    11921099        struct dict_type_data * type = ( struct dict_type_data * ) data;
    1193        
    1194         return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", 
    1195                         type_base_name[type->type_base], 
     1100
     1101        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"",
     1102                        type_base_name[type->type_base],
    11961103                        type->type_name);
    11971104}
     
    12121119                        }
    12131120                        break;
    1214                
     1121
    12151122                case AVP_TYPE_INTEGER32:
    12161123                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL);
     
    12361143                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL);
    12371144                        break;
    1238                
     1145
    12391146                default:
    12401147                        CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL);
     
    12451152{
    12461153        struct dict_avp_data * avp = (struct dict_avp_data * ) data;
    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, 
     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,
    12521159                        avp->avp_name );
    12531160}
     
    12551162{
    12561163        struct dict_cmd_data * cmd = (struct dict_cmd_data *) data;
    1257         return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", 
     1164        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"",
    12581165                        DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name);
    12591166}
     
    12621169        struct dict_rule_data * rule = (struct dict_rule_data * )data;
    12631170        return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"",
    1264                         rule->rule_position, 
    1265                         rule->rule_order, 
    1266                         rule->rule_min, 
     1171                        rule->rule_position,
     1172                        rule->rule_order,
     1173                        rule->rule_min,
    12671174                        rule->rule_max,
    12681175                        rule->rule_avp->data.avp.avp_name);
     
    12911198{
    12921199        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL);
    1293        
     1200
    12941201        if (!verify_object(obj)) {
    12951202                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL);
    12961203                return *buf;
    12971204        }
    1298        
    1299         CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", 
    1300                                                                 _OBINFO(obj).name, 
     1205
     1206        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ",
     1207                                                                _OBINFO(obj).name,
    13011208                                                                obj->parent), return NULL);
    1302        
     1209
    13031210        if (obj->type == DICT_ENUMVAL) {
    13041211                CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL);
     
    13061213                CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL);
    13071214        }
    1308        
     1215
    13091216        if (parents) {
    13101217                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n%*sparent:", indent + 1, ""), return NULL);
    13111218                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL);
    13121219        }
    1313        
     1220
    13141221        if (depth) {
    13151222                int i;
     
    13211228                }
    13221229        }
    1323        
     1230
    13241231        return *buf;
    13251232}
     
    13281235{
    13291236        FD_DUMP_HANDLE_OFFSET();
    1330        
     1237
    13311238        CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL);
    1332        
     1239
    13331240        return *buf;
    13341241}
     
    13381245        int i;
    13391246        struct fd_list * li;
    1340        
     1247
    13411248        FD_DUMP_HANDLE_OFFSET();
    1342                
     1249
    13431250        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL);
    1344        
     1251
    13451252        if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) {
    13461253                return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL");
    13471254        }
    1348        
     1255
    13491256        CHECK_POSIX_DO(  pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */  );
    1350        
     1257
    13511258        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): VENDORS / AVP / RULES\n", dict), goto error);
    13521259        CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error);
     
    13551262                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error);
    13561263        }
    1357        
     1264
    13581265        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): APPLICATIONS\n", dict), goto error);
    13591266        CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error);
     
    13621269                CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error);
    13631270        }
    1364        
     1271
    13651272        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): TYPES / ENUMVAL", dict), goto error);
    13661273        CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error);
    1367        
     1274
    13681275        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): COMMANDS / RULES", dict), goto error);
    13691276        CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error);
    1370        
     1277
    13711278        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict}(@%p): statistics", dict), goto error);
    13721279        for (i=1; i<=DICT_TYPE_MAX; i++)
    13731280                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n   %5d: %s",  dict->dict_count[i], dict_obj_info[i].name), goto error);
    1374        
     1281
    13751282        CHECK_POSIX_DO(  pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */  );
    13761283        return *buf;
    1377 error: 
     1284error:
    13781285        /* Free the rwlock */
    13791286        CHECK_POSIX_DO(  pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */  );
     
    13871294{
    13881295        int i;
    1389        
     1296
    13901297        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL);
    13911298        for (i = 0; i < value->os.len; i++) {
     
    14361343                case AVP_TYPE_OCTETSTRING:
    14371344                        return &dump_val_os;
    1438                
     1345
    14391346                case AVP_TYPE_INTEGER32:
    14401347                        return &dump_val_i32;
     
    14541361                case AVP_TYPE_FLOAT64:
    14551362                        return &dump_val_f64;
    1456                
     1363
    14571364                case AVP_TYPE_GROUPED:
    14581365                        TRACE_DEBUG(FULL, "error: grouped AVP with a value!");
     
    14681375
    14691376/* Formatter for the AVP value dump line */
    1470 static 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, 
     1377static 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,
    14771384                        int header)
    14781385{
     
    14801387                /* Header for all AVP values dumps: */
    14811388                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL);
    1482        
     1389
    14831390                /* If the type is provided, write it */
    14841391                if (type_name) {
    14851392                        CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL);
    14861393                }
    1487        
     1394
    14881395                /* Always give the base datatype anyway */
    14891396                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL);
     
    15031410                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL);
    15041411        }
    1505        
     1412
    15061413        /* Done! */
    15071414        return *buf;
     
    15151422        char * type_name = NULL;
    15161423        char * const_name = NULL;
    1517        
     1424
    15181425        FD_DUMP_HANDLE_OFFSET();
    1519        
     1426
    15201427        /* Handle invalid parameters */
    15211428        if (!avp_value) {
     
    15281435                return *buf;
    15291436        }
    1530        
     1437
    15311438        if (! ( verify_object(model) && (model->type == DICT_AVP) )) {
    15321439                CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(invalid model)"), return NULL);
    15331440                return *buf;
    15341441        }
    1535        
     1442
    15361443        /* Get the type definition of this AVP */
    15371444        type = model->parent;
     
    15391446                struct dict_enumval_request  request;
    15401447                struct dict_object * enumval = NULL;
    1541                
     1448
    15421449                type_name = type->data.type.type_name;
    1543                
     1450
    15441451                /* overwrite the dump function ? */
    15451452                if (type->data.type.type_dump)
    15461453                        dump_val_cb = type->data.type.type_dump;
    1547                
     1454
    15481455                /* Now check if the AVP value matches a constant */
    15491456                memset(&request, 0, sizeof(request));
     
    15561463                }
    15571464        }
    1558        
     1465
    15591466        /* And finally, dump the value */
    15601467        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 );
     
    15761483{
    15771484        TRACE_ENTRY("%p %p", object, type);
    1578        
     1485
    15791486        CHECK_PARAMS( type && verify_object(object) );
    1580        
     1487
    15811488        /* Copy the value and return */
    15821489        *type = object->type;
     
    15871494{
    15881495        TRACE_ENTRY("%p %p", object, dict);
    1589        
     1496
    15901497        CHECK_PARAMS( dict && verify_object(object) );
    1591        
     1498
    15921499        /* Copy the value and return */
    15931500        *dict = object->dico;
     
    16001507{
    16011508        TRACE_ENTRY("%p %p", object, val);
    1602        
     1509
    16031510        CHECK_PARAMS( val && verify_object(object) );
    1604        
     1511
    16051512        /* Copy the value and return */
    16061513        memcpy(val, &object->data, _OBINFO(object).datasize);;
     
    16161523        struct dict_object * vendor = NULL;
    16171524        struct dict_object * locref = NULL;
    1618        
     1525
    16191526        TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref);
    1620        
     1527
    16211528        /* Check parameters */
    16221529        CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) && data  );
    1623        
     1530
    16241531        /* Check the "parent" parameter */
    16251532        switch (dict_obj_info[type].parent) {
    16261533                case 0: /* parent is forbidden */
    16271534                        CHECK_PARAMS_DO( parent == NULL, goto error_param );
    1628                
     1535
    16291536                case 1: /* parent is optional */
    16301537                        if (parent == NULL)
    16311538                                break;
    1632                
     1539
    16331540                case 2: /* parent is mandatory */
    16341541                        CHECK_PARAMS_DO(  verify_object(parent), goto error_param  );
    1635                        
     1542
    16361543                        if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */
    1637                                 CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) 
     1544                                CHECK_PARAMS_DO( (parent->type == DICT_COMMAND )
    16381545                                                || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param );
    16391546                        } else {
     
    16411548                        }
    16421549        }
    1643        
     1550
    16441551        /* For AVP object, we must also check that the "vendor" referenced exists */
    16451552        if (type == DICT_AVP) {
    16461553                CHECK_FCT_DO(  fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ),
    16471554                        { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; }  );
    1648                
     1555
    16491556                /* Also check if a parent is provided, that the type are the same */
    16501557                if (parent) {
     
    16521559                }
    16531560        }
    1654        
     1561
    16551562        /* For RULE object, we must also check that the "avp" referenced exists */
    16561563        if (type == DICT_RULE) {
     
    16581565                CHECK_PARAMS_DO(  ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param  );
    16591566        }
    1660        
     1567
    16611568        /* For COMMAND object, check that the 'R' flag is fixed */
    16621569        if (type == DICT_COMMAND) {
     
    16691576                        dupos = 1;
    16701577        }
    1671        
     1578
    16721579        /* We have to check that the new values are not equal to the sentinels */
    16731580        if (type == DICT_VENDOR) {
     
    16771584                CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param   );
    16781585        }
    1679        
     1586
    16801587        /* Parameters are valid, create the new object */
    16811588        CHECK_MALLOC(  new = malloc(sizeof(struct dict_object))  );
    1682        
     1589
    16831590        /* Initialize the data of the new object */
    16841591        init_object(new, type);
     
    16861593        new->dico = dict;
    16871594        new->parent = parent;
    1688        
     1595
    16891596        /* We will change the dictionary => acquire the write lock */
    16901597        CHECK_POSIX_DO(  ret = pthread_rwlock_wrlock(&dict->dict_lock),  goto error_free  );
    1691        
     1598
    16921599        /* Now link the object -- this also checks that no object with same keys already exists */
    16931600        switch (type) {
     
    16981605                                goto error_unlock;
    16991606                        break;
    1700                
     1607
    17011608                case DICT_APPLICATION:
    17021609                        /* An application object is linked in the g_dict_applciations.list[0], by their id */
     
    17051612                                goto error_unlock;
    17061613                        break;
    1707                
     1614
    17081615                case DICT_TYPE:
    17091616                        /* A type object is linked in g_list_types by its name */
     
    17121619                                goto error_unlock;
    17131620                        break;
    1714                
     1621
    17151622                case DICT_ENUMVAL:
    17161623                        /* A type_enum object is linked in it's parent 'type' object lists 1 and 2 by its name and values */
     
    17181625                        if (ret)
    17191626                                goto error_unlock;
    1720                        
     1627
    17211628                        ret = fd_list_insert_ordered ( &parent->list[2], &new->list[1], (int (*)(void*, void *))order_enum_by_val, (void **)&locref );
    1722                         if (ret) { 
    1723                                 fd_list_unlink(&new->list[0]); 
    1724                                 goto error_unlock; 
     1629                        if (ret) {
     1630                                fd_list_unlink(&new->list[0]);
     1631                                goto error_unlock;
    17251632                        }
    17261633                        break;
    1727                
     1634
    17281635                case DICT_AVP:
    17291636                        /* An avp object is linked in lists 1 and 2 of its vendor, by code and name */
     
    17311638                        if (ret)
    17321639                                goto error_unlock;
    1733                        
     1640
    17341641                        ret = fd_list_insert_ordered ( &vendor->list[2], &new->list[1], (int (*)(void*, void *))order_avp_by_name, (void **)&locref );
    17351642                        if (ret) {
     
    17381645                        }
    17391646                        break;
    1740                        
     1647
    17411648                case DICT_COMMAND:
    17421649                        /* A command object is linked in g_list_cmd_name and g_list_cmd_code by its name and code */
     
    17441651                        if (ret)
    17451652                                goto error_unlock;
    1746                        
     1653
    17471654                        ret = fd_list_insert_ordered ( &dict->dict_cmd_name, &new->list[0], (int (*)(void*, void *))order_cmd_by_name, (void **)&locref );
    17481655                        if (ret) {
     
    17511658                        }
    17521659                        break;
    1753                
     1660
    17541661                case DICT_RULE:
    17551662                        /* A rule object is linked in list[2] of its parent command or AVP by the name of the AVP it refers */
     
    17581665                                goto error_unlock;
    17591666                        break;
    1760                        
     1667
    17611668                default:
    17621669                        ASSERT(0);
    17631670        }
    1764        
     1671
    17651672        /* A new object has been created, increment the global counter */
    17661673        dict->dict_count[type]++;
    1767        
     1674
    17681675        /* Unlock the dictionary */
    17691676        CHECK_POSIX_DO(  ret = pthread_rwlock_unlock(&dict->dict_lock),  goto error_free  );
    1770        
     1677
    17711678        /* Save the pointer to the new object */
    17721679        if (ref)
    17731680                *ref = new;
    1774        
     1681
    17751682        return 0;
    1776        
     1683
    17771684error_param:
    17781685        ret = EINVAL;
     
    17871694                                TRACE_DEBUG(FULL, "Vendor %s already in dictionary", new->data.vendor.vendor_name);
    17881695                                /* if we are here, it means the two vendors id are identical */
    1789                                 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, 
     1696                                if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len,
    17901697                                                new->data.vendor.vendor_name, new->datastr_len)) {
    17911698                                        TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name);
     
    17931700                                }
    17941701                                /* Otherwise (same name), we consider the function succeeded, since the (same) object is in the dictionary */
    1795                                 ret = 0; 
     1702                                ret = 0;
    17961703                                break;
    17971704
     
    17991706                                TRACE_DEBUG(FULL, "Application %s already in dictionary", new->data.application.application_name);
    18001707                                /* got same id */
    1801                                 if (fd_os_cmp(locref->data.application.application_name, locref->datastr_len, 
     1708                                if (fd_os_cmp(locref->data.application.application_name, locref->datastr_len,
    18021709                                                new->data.application.application_name, new->datastr_len)) {
    18031710                                        TRACE_DEBUG(FULL, "Conflicting application name");
     
    19371844                char * buf = NULL;
    19381845                size_t len = 0, offset=0;
    1939                
     1846
    19401847                if (type == DICT_ENUMVAL) {
    19411848                        CHECK_MALLOC( dump_enumval_data ( &buf, &len, &offset, data, parent->data.type.type_base ));
     
    19431850                        CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, &offset, data) );
    19441851                }
    1945        
     1852
    19461853                TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf);
    1947                
     1854
    19481855                if (ret == EEXIST) {
    19491856                        offset=0;
     
    19641871        struct dictionary * dict;
    19651872        int ret=0;
    1966        
     1873
    19671874        /* check params */
    19681875        CHECK_PARAMS( verify_object(obj) && obj->dico);
     
    19711878        /* Lock the dictionary for change */
    19721879        CHECK_POSIX(  pthread_rwlock_wrlock(&dict->dict_lock)  );
    1973        
     1880
    19741881        /* check the object is not sentinel for another list */
    19751882        for (i=0; i<NB_LISTS_PER_OBJ; i++) {
     
    19841891                }
    19851892        }
    1986        
     1893
    19871894        /* ok, now destroy the object */
    19881895        if (!ret)
    19891896                destroy_object(obj);
    1990        
     1897
    19911898        /* Unlock */
    19921899        CHECK_POSIX(  pthread_rwlock_unlock(&dict->dict_lock)  );
    1993        
     1900
    19941901        return ret;
    19951902}
     
    19991906{
    20001907        int ret = 0;
    2001        
     1908
    20021909        TRACE_ENTRY("%p %d(%s) %d %p %p %d", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, criteria, what, result, retval);
    2003        
     1910
    20041911        /* Check param */
    20051912        CHECK_PARAMS( dict && (dict->dict_eyec == DICT_EYECATCHER) && CHECK_TYPE(type) );
    2006        
     1913
    20071914        /* Lock the dictionary for reading */
    20081915        CHECK_POSIX(  pthread_rwlock_rdlock(&dict->dict_lock)  );
    2009        
     1916
    20101917        /* Now call the type-specific search function */
    20111918        ret = dict_obj_info[type].search_fct (dict, criteria, what, result);
    2012        
     1919
    20131920        /* Unlock */
    20141921        CHECK_POSIX(  pthread_rwlock_unlock(&dict->dict_lock)  );
    2015        
     1922
    20161923        /* Update the return value as needed */
    20171924        if ((result != NULL) && (*result == NULL))
    20181925                ret = retval;
    2019        
     1926
    20201927        return ret;
    20211928}
     
    20301937  }
    20311938
    2032 The following criteria are allowed, with corresponding parent. 
     1939The following criteria are allowed, with corresponding parent.
    20331940The parent is either struct dictionary * or struct dict_object *
    2034                
     1941
    20351942VENDOR_BY_ID : (parent = dictionary) returns list of vendors ordered by ID
    20361943APPLICATION_BY_ID : (parent = dictionary) returns list of applications ordered by ID
    2037   ** for these two lists, the Vendor with id 0 and applciation with id 0 are excluded. 
     1944  ** for these two lists, the Vendor with id 0 and applciation with id 0 are excluded.
    20381945     You must resolve them separatly with dict_search.
    2039                
     1946
    20401947TYPE_BY_NAME : (parent = dictionary) returns list of types ordered by name (osstring order)
    20411948ENUMVAL_BY_NAME : (parent = type object) return list of constants for this type ordered by name (osstring order)
     
    20531960        struct dictionary * dict = parent;
    20541961        struct dict_object * obj_parent = parent;
    2055        
     1962
    20561963        TRACE_ENTRY("%i %p %p", criteria, parent, sentinel);
    2057        
     1964
    20581965        CHECK_PARAMS(sentinel && parent);
    2059        
     1966
    20601967        switch(criteria) {
    20611968                case VENDOR_BY_ID: /* parent must be the dictionary */
     
    20631970                        *sentinel = &dict->dict_vendors.list[0];
    20641971                        break;
    2065                        
     1972
    20661973                case APPLICATION_BY_ID: /* parent must be the dictionary */
    20671974                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    20681975                        *sentinel = &dict->dict_applications.list[0];
    20691976                        break;
    2070                        
     1977
    20711978                case TYPE_BY_NAME: /* parent must be the dictionary */
    20721979                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    20731980                        *sentinel = &dict->dict_types;
    20741981                        break;
    2075                        
     1982
    20761983                case ENUMVAL_BY_NAME: /* parent must be a type object */
    20771984                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE));
    20781985                        *sentinel = &obj_parent->list[1];
    20791986                        break;
    2080                        
     1987
    20811988                case ENUMVAL_BY_VALUE: /* parent must be a type object */
    20821989                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_TYPE));
    20831990                        *sentinel = &obj_parent->list[2];
    20841991                        break;
    2085                        
     1992
    20861993                case AVP_BY_NAME: /* parent must be a VENDOR object */
    20871994                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR));
    20881995                        *sentinel = &obj_parent->list[2];
    20891996                        break;
    2090                        
     1997
    20911998                case AVP_BY_CODE: /* parent must be a VENDOR object */
    20921999                        CHECK_PARAMS(verify_object(obj_parent) && (obj_parent->type == DICT_VENDOR));
    20932000                        *sentinel = &obj_parent->list[1];
    20942001                        break;
    2095                        
     2002
    20962003                case CMD_BY_NAME: /* parent must be the dictionary */
    20972004                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    20982005                        *sentinel = &dict->dict_cmd_name;
    20992006                        break;
    2100                        
     2007
    21012008                case CMD_BY_CODE_R: /* parent must be the dictionary */
    21022009                        CHECK_PARAMS(dict->dict_eyec == DICT_EYECATCHER);
    21032010                        *sentinel = &dict->dict_cmd_code;
    21042011                        break;
    2105                        
     2012
    21062013                case RULE_BY_AVP_AND_PARENT: /* parent must be command or grouped AVP */
    21072014                        CHECK_PARAMS(verify_object(obj_parent));
    21082015                        CHECK_PARAMS(   (obj_parent->type == DICT_COMMAND) ||
    2109                                         ((obj_parent->type == DICT_AVP) 
     2016                                        ((obj_parent->type == DICT_AVP)
    21102017                                          && (obj_parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) );
    21112018                        *sentinel = &obj_parent->list[2];
    21122019                        break;
    2113                        
     2020
    21142021                default:
    21152022                        CHECK_PARAMS(0);
    21162023        }
    2117        
     2024
    21182025        return 0;
    21192026}
     
    21312038{
    21322039        struct dictionary * new = NULL;
    2133        
     2040
    21342041        TRACE_ENTRY("%p", dict);
    2135        
     2042
    21362043        /* Sanity checks */
    21372044        ASSERT( (sizeof(type_base_name) / sizeof(type_base_name[0])) == (AVP_TYPE_MAX + 1) );
    21382045        ASSERT( (sizeof(dict_obj_info)  / sizeof(dict_obj_info[0]))  == (DICT_TYPE_MAX + 1) );
    21392046        CHECK_PARAMS(dict);
    2140        
     2047
    21412048        /* Allocate the memory for the dictionary */
    21422049        CHECK_MALLOC( new = malloc(sizeof(struct dictionary)) );
    21432050        memset(new, 0, sizeof(struct dictionary));
    2144        
     2051
    21452052        new->dict_eyec = DICT_EYECATCHER;
    2146        
     2053
    21472054        /* Initialize the lock for the dictionary */
    21482055        CHECK_POSIX(  pthread_rwlock_init(&new->dict_lock, NULL)  );
    2149        
     2056
    21502057        /* Initialize the sentinel for vendors and AVP lists */
    21512058        init_object( &new->dict_vendors, DICT_VENDOR );
     
    21552062        /* new->dict_vendors.list[0].o = NULL; *//* overwrite since element is also sentinel for this list. */
    21562063        new->dict_vendors.dico = new;
    2157        
     2064
    21582065        /* Initialize the sentinel for applications */
    21592066        init_object( &new->dict_applications, DICT_APPLICATION );
     
    21632070        /* new->dict_applications.list[0].o = NULL; *//* overwrite since since element is also sentinel for this list. */
    21642071        new->dict_applications.dico = new;
    2165                        
     2072
    21662073        /* Initialize the sentinel for types */
    21672074        fd_list_init ( &new->dict_types, NULL );
    2168        
     2075
    21692076        /* Initialize the sentinels for commands */
    21702077        fd_list_init ( &new->dict_cmd_name, NULL );
    21712078        fd_list_init ( &new->dict_cmd_code, NULL );
    2172        
     2079
    21732080        /* Initialize the error command object */
    21742081        init_object( &new->dict_cmd_error, DICT_COMMAND );
     
    21792086        new->dict_cmd_error.data.cmd.cmd_flag_val =CMD_FLAG_ERROR;
    21802087        new->dict_cmd_error.dico = new;
    2181        
     2088
    21822089        *dict = new;
    2183        
     2090
    21842091        /* Done */
    21852092        return 0;
     
    21902097{
    21912098        int i;
    2192        
     2099
    21932100        TRACE_ENTRY("");
    21942101        CHECK_PARAMS( dict && *dict && ((*dict)->dict_eyec == DICT_EYECATCHER) );
    2195        
     2102
    21962103        /* Acquire the write lock to make sure no other operation is ongoing */
    21972104        CHECK_POSIX(  pthread_rwlock_wrlock(&(*dict)->dict_lock)  );
    2198        
     2105
    21992106        /* Empty all the lists, free the elements */
    22002107        destroy_list ( &(*dict)->dict_cmd_error.list[2] );
     
    22062113                destroy_list ( &(*dict)->dict_vendors.list[i] );
    22072114        }
    2208        
     2115
    22092116        /* Dictionary is empty, now destroy the lock */
    22102117        CHECK_POSIX(  pthread_rwlock_unlock(&(*dict)->dict_lock)  );
    22112118        CHECK_POSIX(  pthread_rwlock_destroy(&(*dict)->dict_lock)  );
    2212        
     2119
    22132120        free(*dict);
    22142121        *dict = NULL;
    2215        
     2122
    22162123        return 0;
    22172124}
     
    22302137        int ret = 0;
    22312138        struct fd_list * li;
    2232        
     2139
    22332140        TRACE_ENTRY("%p %p %p", parent, data, cb);
    2234        
     2141
    22352142        /* Check parameters */
    22362143        CHECK_PARAMS(  verify_object(parent)  );
    2237         CHECK_PARAMS(  (parent->type == DICT_COMMAND) 
     2144        CHECK_PARAMS(  (parent->type == DICT_COMMAND)
    22382145                        || ((parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED)) );
    2239         TRACE_DEBUG (FULL, "Iterating on rules of %s: '%s'.", 
    2240                         _OBINFO(parent).name, 
    2241                         parent->type == DICT_COMMAND ? 
     2146        TRACE_DEBUG (FULL, "Iterating on rules of %s: '%s'.",
     2147                        _OBINFO(parent).name,
     2148                        parent->type == DICT_COMMAND ?
    22422149                                  parent->data.cmd.cmd_name
    22432150                                : parent->data.avp.avp_name);
    2244        
     2151
    22452152        /* Acquire the read lock  */
    22462153        CHECK_POSIX(  pthread_rwlock_rdlock(&parent->dico->dict_lock)  );
    2247        
     2154
    22482155        /* go through the list and call the cb on each rule data */
    22492156        for (li = &(parent->list[2]); li->next != &(parent->list[2]); li = li->next) {
     
    22522159                        break;
    22532160        }
    2254                
     2161
    22552162        /* Release the lock */
    22562163        CHECK_POSIX(  pthread_rwlock_unlock(&parent->dico->dict_lock)  );
    2257        
     2164
    22582165        return ret;
    22592166}
     
    22652172        int i = 0;
    22662173        struct fd_list * li;
    2267        
     2174
    22682175        TRACE_ENTRY();
    2269        
     2176
    22702177        /* Acquire the read lock */
    22712178        CHECK_POSIX_DO(  pthread_rwlock_rdlock(&dict->dict_lock), return NULL  );
    2272        
     2179
    22732180        /* Allocate an array to contain all the elements */
    22742181        CHECK_MALLOC_DO( ret = calloc( dict->dict_count[DICT_VENDOR] + 1, sizeof(uint32_t) ), goto out );
    2275        
     2182
    22762183        /* Copy the vendors IDs */
    22772184        for (li = dict->dict_vendors.list[0].next; li != &(dict->dict_vendors.list[0]); li = li->next) {
     
    22802187                ASSERT( i <= dict->dict_count[DICT_VENDOR] );
    22812188        }
    2282 out:   
     2189out:
    22832190        /* Release the lock */
    22842191        CHECK_POSIX_DO(  pthread_rwlock_unlock(&dict->dict_lock), return NULL  );
    2285        
     2192
    22862193        return ret;
    22872194}
Note: See TracChangeset for help on using the changeset viewer.