Changeset 1085:7d7266115a34 in freeDiameter for libfdproto/dictionary.c
- Timestamp:
- May 3, 2013, 8:20:56 PM (11 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdproto/dictionary.c
r1052 r1085 148 148 149 149 /* Forward declarations of dump functions */ 150 static void dump_vendor_data (void * data );151 static void dump_application_data (void * data );152 static void dump_type_data (void * data );150 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ); 151 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ); 152 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ); 153 153 /* the dump function for enum has a different prototype since it need the datatype */ 154 static void dump_avp_data (void * data );155 static void dump_command_data (void * data );156 static void dump_rule_data (void * data );154 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ); 155 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ); 156 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ); 157 157 158 158 /* Forward declarations of search functions */ … … 173 173 enum dict_object_type parenttype; /* The type of the parent, when relevant */ 174 174 int eyecatcher; /* A kind of signature for this object */ 175 void (*dump_data)(void * data ); /* The function to dump the data section */175 DECLARE_FD_DUMP_PROTOTYPE( (*dump_data), void * data ); /* The function to dump the data section */ 176 176 int (*search_fct)(struct dictionary * dict, int criteria, const void * what, struct dict_object **result );; /* The function to search an object of this type */ 177 177 int haslist[NB_LISTS_PER_OBJ]; /* Tell if this list is used */ … … 1150 1150 /*******************************************************************************************************/ 1151 1151 /* The following functions are used to debug the module, and allow to print out the content of the dictionary */ 1152 static void dump_vendor_data (void * data )1152 static DECLARE_FD_DUMP_PROTOTYPE(dump_vendor_data, void * data ) 1153 1153 { 1154 1154 struct dict_vendor_data * vendor = (struct dict_vendor_data *)data; 1155 1155 1156 fd_log_debug("data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name);1157 } 1158 static void dump_application_data (void * data )1156 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", vendor->vendor_id, vendor->vendor_name); 1157 } 1158 static DECLARE_FD_DUMP_PROTOTYPE(dump_application_data, void * data ) 1159 1159 { 1160 1160 struct dict_application_data * appli = (struct dict_application_data *) data; 1161 fd_log_debug("data: %-6u \"%s\"", appli->application_id, appli->application_name);1162 } 1163 static void dump_type_data (void * data )1161 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-6u \"%s\"", appli->application_id, appli->application_name); 1162 } 1163 static DECLARE_FD_DUMP_PROTOTYPE(dump_type_data, void * data ) 1164 1164 { 1165 1165 struct dict_type_data * type = ( struct dict_type_data * ) data; 1166 1166 1167 fd_log_debug("data: %-12s \"%s\"",1167 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: %-12s \"%s\"", 1168 1168 type_base_name[type->type_base], 1169 1169 type->type_name); 1170 1170 } 1171 static void dump_enumval_data (struct dict_enumval_data * enumval, enum dict_avp_basetype type )1171 static DECLARE_FD_DUMP_PROTOTYPE(dump_enumval_data, struct dict_enumval_data * enumval, enum dict_avp_basetype type ) 1172 1172 { 1173 1173 const int LEN_MAX = 20; 1174 fd_log_debug("data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name);1174 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "data: (%-12s) \"%s\" -> ", type_base_name[type], enumval->enum_name), return NULL); 1175 1175 switch (type) { 1176 1176 case AVP_TYPE_OCTETSTRING: … … 1180 1180 n = enumval->enum_value.os.len; 1181 1181 for (i=0; i < n; i++) 1182 fd_log_debug("0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i]));1182 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "0x%2hhX/'%c' ", enumval->enum_value.os.data[i], ASCII(enumval->enum_value.os.data[i])), return NULL); 1183 1183 if (n == LEN_MAX) 1184 fd_log_debug("...");1184 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "..."), return NULL); 1185 1185 } 1186 1186 break; 1187 1187 1188 1188 case AVP_TYPE_INTEGER32: 1189 fd_log_debug("%i", enumval->enum_value.i32);1189 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%i", enumval->enum_value.i32), return NULL); 1190 1190 break; 1191 1191 1192 1192 case AVP_TYPE_INTEGER64: 1193 fd_log_debug("%"PRId64, enumval->enum_value.i64);1193 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRId64, enumval->enum_value.i64), return NULL); 1194 1194 break; 1195 1195 1196 1196 case AVP_TYPE_UNSIGNED32: 1197 fd_log_debug("%u", enumval->enum_value.u32);1197 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%u", enumval->enum_value.u32), return NULL); 1198 1198 break; 1199 1199 1200 1200 case AVP_TYPE_UNSIGNED64: 1201 fd_log_debug("%"PRIu64, enumval->enum_value.u64);1201 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%"PRIu64, enumval->enum_value.u64), return NULL); 1202 1202 break; 1203 1203 1204 1204 case AVP_TYPE_FLOAT32: 1205 fd_log_debug("%f", enumval->enum_value.f32);1205 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", enumval->enum_value.f32), return NULL); 1206 1206 break; 1207 1207 1208 1208 case AVP_TYPE_FLOAT64: 1209 fd_log_debug("%g", enumval->enum_value.f64);1209 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", enumval->enum_value.f64), return NULL); 1210 1210 break; 1211 1211 1212 1212 default: 1213 fd_log_debug("??? (ERROR unknown type %d)", type); 1214 } 1215 } 1216 static void dump_avp_data ( void * data ) 1213 CHECK_MALLOC_DO(fd_dump_extend( FD_DUMP_STD_PARAMS, "??? (ERROR unknown type %d)", type), return NULL); 1214 } 1215 return *buf; 1216 } 1217 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_data, void * data ) 1217 1218 { 1218 1219 struct dict_avp_data * avp = (struct dict_avp_data * ) data; 1219 fd_log_debug("data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"",1220 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %-6u \"%s\"", 1220 1221 DUMP_AVPFL_val(avp->avp_flag_val), 1221 1222 DUMP_AVPFL_val(avp->avp_flag_mask), … … 1224 1225 avp->avp_name ); 1225 1226 } 1226 static void dump_command_data (void * data )1227 static DECLARE_FD_DUMP_PROTOTYPE(dump_command_data, void * data ) 1227 1228 { 1228 1229 struct dict_cmd_data * cmd = (struct dict_cmd_data *) data; 1229 fd_log_debug("data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"",1230 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %-6u \"%s\"", 1230 1231 DUMP_CMDFL_val(cmd->cmd_flag_val), DUMP_CMDFL_val(cmd->cmd_flag_mask), cmd->cmd_code, cmd->cmd_name); 1231 1232 } 1232 static void dump_rule_data (void * data )1233 static DECLARE_FD_DUMP_PROTOTYPE(dump_rule_data, void * data ) 1233 1234 { 1234 1235 struct dict_rule_data * rule = (struct dict_rule_data * )data; 1235 fd_log_debug("data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"",1236 return fd_dump_extend( FD_DUMP_STD_PARAMS, "data: pos:%d ord:%d m/M:%2d/%2d avp:\"%s\"", 1236 1237 rule->rule_position, 1237 1238 rule->rule_order, … … 1241 1242 } 1242 1243 1243 static void dump_object (struct dict_object * obj, int parents, int depth, int indent );1244 1245 static void dump_list (struct fd_list * sentinel, int parents, int depth, int indent )1244 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ); 1245 1246 static DECLARE_FD_DUMP_PROTOTYPE(dump_list, struct fd_list * sentinel, int parents, int depth, int indent ) 1246 1247 { 1247 1248 struct fd_list * li = sentinel; … … 1250 1251 { 1251 1252 li = li->next; 1252 dump_object( _O(li->o), parents, depth, indent ); 1253 } 1254 } 1255 1256 static void dump_object ( struct dict_object * obj, int parents, int depth, int indent ) 1257 { 1258 if (obj == NULL) 1259 return; 1260 1261 if (parents) 1262 dump_object (obj->parent, parents-1, 0, indent + 1 ); 1263 1264 fd_log_debug("%*s@%p: %s%s (p:%-9p) ", 1265 indent, 1266 "", 1267 obj, 1268 verify_object(obj) ? "" : "INVALID ", 1269 _OBINFO(obj).name, 1270 obj->parent); 1271 1272 if (obj->type == DICT_ENUMVAL) 1273 dump_enumval_data ( &obj->data.enumval, obj->parent->data.type.type_base ); 1274 else 1275 _OBINFO(obj).dump_data(&obj->data); 1253 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, _O(li->o), parents, depth, indent ), return NULL); 1254 } 1255 } 1256 1257 static DECLARE_FD_DUMP_PROTOTYPE(dump_object, struct dict_object * obj, int parents, int depth, int indent ) 1258 { 1259 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*s{dictobj}(@%p): ", indent, "", obj), return NULL); 1260 1261 if (!verify_object(obj)) { 1262 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL\n"), return NULL); 1263 return *buf; 1264 } 1265 1266 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s p:%p ", 1267 _OBINFO(obj).name, 1268 obj->parent), return NULL); 1269 1270 if (obj->type == DICT_ENUMVAL) { 1271 CHECK_MALLOC_DO( dump_enumval_data ( FD_DUMP_STD_PARAMS, &obj->data.enumval, obj->parent->data.type.type_base ), return NULL); 1272 } else { 1273 CHECK_MALLOC_DO( _OBINFO(obj).dump_data(FD_DUMP_STD_PARAMS, &obj->data), return NULL); 1274 } 1275 1276 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL); 1277 1278 if (parents) { 1279 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*sparent:", indent + 1, ""), return NULL); 1280 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, obj->parent, parents-1, 0, 0 ), return NULL); 1281 } 1276 1282 1277 1283 if (depth) { … … 1279 1285 for (i=0; i<NB_LISTS_PER_OBJ; i++) { 1280 1286 if ((obj->list[i].o == NULL) && (obj->list[i].next != &obj->list[i])) { 1281 fd_log_debug("%*s>%p: list[%d]:", indent, "", obj, i);1282 dump_list(&obj->list[i], parents, depth - 1, indent + 2);1287 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%*slist[%d]:\n", indent + 1, "", i), return NULL); 1288 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &obj->list[i], 0, depth - 1, indent + 2), return NULL); 1283 1289 } 1284 1290 } 1285 1291 } 1286 } 1287 1288 void fd_dict_dump_object(struct dict_object * obj) 1289 { 1290 fd_log_debug("Dictionary object %p dump:", obj); 1291 dump_object( obj, 1, 2, 2 ); 1292 } 1293 1294 void fd_dict_dump(struct dictionary * dict) 1292 1293 return *buf; 1294 } 1295 1296 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_object, struct dict_object * obj) 1297 { 1298 size_t o = 0; 1299 1300 if (!offset) 1301 offset = &o; 1302 1303 CHECK_MALLOC_DO( dump_object(FD_DUMP_STD_PARAMS, obj, 1, 2, 0), return NULL); 1304 1305 return *buf; 1306 } 1307 1308 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump, struct dictionary * dict) 1295 1309 { 1296 1310 int i; 1297 1311 struct fd_list * li; 1298 1299 CHECK_PARAMS_DO(dict && (dict->dict_eyec == DICT_EYECATCHER), return); 1312 size_t o = 0; 1313 1314 if (!offset) 1315 offset = &o; 1316 1317 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{dictionary}(@%p): ", dict), return NULL); 1318 1319 if ((dict == NULL) || (dict->dict_eyec != DICT_EYECATCHER)) { 1320 return fd_dump_extend(FD_DUMP_STD_PARAMS, "INVALID/NULL\n"); 1321 } 1300 1322 1301 1323 CHECK_POSIX_DO( pthread_rwlock_rdlock( &dict->dict_lock ), /* ignore */ ); 1302 1324 1303 fd_log_debug("######################################################"); 1304 fd_log_debug("###### Dumping vendors, AVPs and related rules #######"); 1305 1306 dump_object( &dict->dict_vendors, 0, 3, 0 ); 1325 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {dict:%p > vendors, AVPs and related rules}\n", dict), goto error); 1326 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_vendors, 0, 3, 3 ), goto error); 1307 1327 for (li = dict->dict_vendors.list[0].next; li != &dict->dict_vendors.list[0]; li = li->next) 1308 dump_object( li->o, 0, 3, 0 ); 1309 1310 fd_log_debug("###### Dumping applications #######"); 1311 1312 dump_object( &dict->dict_applications, 0, 1, 0 ); 1328 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 3, 3 ), goto error); 1329 1330 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > applications}\n", dict), goto error); 1331 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, &dict->dict_applications, 0, 1, 3 ), goto error); 1313 1332 for (li = dict->dict_applications.list[0].next; li != &dict->dict_applications.list[0]; li = li->next) 1314 dump_object( li->o, 0, 1, 0 ); 1315 1316 fd_log_debug("###### Dumping types #######"); 1317 1318 dump_list( &dict->dict_types, 0, 2, 0 ); 1319 1320 fd_log_debug("###### Dumping commands per name #######"); 1321 1322 dump_list( &dict->dict_cmd_name, 0, 2, 0 ); 1323 1324 fd_log_debug("###### Dumping commands per code and flags #######"); 1325 1326 dump_list( &dict->dict_cmd_code, 0, 0, 0 ); 1327 1328 fd_log_debug("###### Statistics #######"); 1329 1333 CHECK_MALLOC_DO( dump_object (FD_DUMP_STD_PARAMS, li->o, 0, 1, 3 ), goto error); 1334 1335 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > types}\n", dict), goto error); 1336 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_types, 0, 2, 3 ), goto error); 1337 1338 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > commands}\n", dict), goto error); 1339 CHECK_MALLOC_DO( dump_list(FD_DUMP_STD_PARAMS, &dict->dict_cmd_code, 0, 0, 3 ), goto error); 1340 1341 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {dict:%p > statistics}\n", dict), goto error); 1330 1342 for (i=1; i<=DICT_TYPE_MAX; i++) 1331 fd_log_debug(" %5d objects of type %s", dict->dict_count[i], dict_obj_info[i].name); 1332 1333 fd_log_debug("######################################################"); 1334 1343 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " %5d: %s\n", dict->dict_count[i], dict_obj_info[i].name), goto error); 1344 1345 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); 1346 return *buf; 1347 error: 1335 1348 /* Free the rwlock */ 1336 1349 CHECK_POSIX_DO( pthread_rwlock_unlock( &dict->dict_lock ), /* ignore */ ); 1350 return NULL; 1337 1351 } 1338 1352 … … 1340 1354 1341 1355 /* Default dump functions */ 1342 static int dump_val_os(union avp_value * value, char **outstr, size_t *offset, size_t *outlen)1356 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_os, union avp_value * value) 1343 1357 { 1344 1358 int i; 1345 CHECK_FCT( dump_add_str(outstr, offset, outlen, "<") ); 1359 1360 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "<"), return NULL); 1346 1361 for (i = 0; i < value->os.len; i++) { 1347 1362 if (i == 1024) { /* Dump only up to 1024 bytes of the buffer */ 1348 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "[...] (len=%zd)", value->os.len));1363 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[...] (len=%zd)", value->os.len), return NULL); 1349 1364 break; 1350 1365 } 1351 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s%02.2X", (i==0 ? "" : " "), value->os.data[i]) ); 1352 } 1353 CHECK_FCT( dump_add_str(outstr, offset, outlen, ">") ); 1354 return 0; 1355 } 1356 1357 static int dump_val_i32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1358 { 1359 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%i (0x%x)", value->i32, value->i32) ); 1360 return 0; 1361 } 1362 1363 static int dump_val_i64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1364 { 1365 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%lli (0x%llx)", value->i64, value->i64) ); 1366 return 0; 1367 } 1368 1369 static int dump_val_u32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1370 { 1371 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%u (0x%x)", value->u32, value->u32) ); 1372 return 0; 1373 } 1374 1375 static int dump_val_u64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1376 { 1377 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%llu (0x%llx)", value->u64, value->u64) ); 1378 return 0; 1379 } 1380 1381 static int dump_val_f32(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1382 { 1383 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%f", value->f32) ); 1384 return 0; 1385 } 1386 1387 static int dump_val_f64(union avp_value * value, char **outstr, size_t *offset, size_t *outlen) 1388 { 1389 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%g", value->f64) ); 1390 return 0; 1366 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%s%02hhX", (i==0 ? "" : " "), value->os.data[i]), return NULL); 1367 } 1368 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ">"), return NULL); 1369 return *buf; 1370 } 1371 1372 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i32, union avp_value * value) 1373 { 1374 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%i (0x%x)", value->i32, value->i32); 1375 } 1376 1377 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_i64, union avp_value * value) 1378 { 1379 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRId64 " (0x%" PRIx64 ")", value->i64, value->i64); 1380 } 1381 1382 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u32, union avp_value * value) 1383 { 1384 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%u (0x%x)", value->u32, value->u32); 1385 } 1386 1387 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_u64, union avp_value * value) 1388 { 1389 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%" PRIu64 " (0x%" PRIx64 ")", value->u64, value->u64); 1390 } 1391 1392 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f32, union avp_value * value) 1393 { 1394 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%f", value->f32); 1395 } 1396 1397 static DECLARE_FD_DUMP_PROTOTYPE(dump_val_f64, union avp_value * value) 1398 { 1399 return fd_dump_extend( FD_DUMP_STD_PARAMS, "%g", value->f64); 1391 1400 } 1392 1401 1393 1402 /* Get the dump function for basic dict_avp_basetype */ 1394 static int (*get_default_dump_val_cb(enum dict_avp_basetype datatype))(union avp_value *, char **, size_t *, size_t*)1403 static DECLARE_FD_DUMP_PROTOTYPE((*get_default_dump_val_cb(enum dict_avp_basetype datatype)), union avp_value *) 1395 1404 { 1396 1405 switch (datatype) { … … 1426 1435 #define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|" 1427 1436 1437 typedef DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb_t), union avp_value *); 1438 1428 1439 /* Formatter for the AVP value dump line */ 1429 static int dump_avp_val(union avp_value *avp_value,1430 int (*def_dump_val_cb)(union avp_value *, char **, size_t *, size_t *),1431 char * (*dump_val_cb)(union avp_value *),1440 static DECLARE_FD_DUMP_PROTOTYPE(dump_avp_val, union avp_value *avp_value, 1441 dump_val_cb_t def_dump_val_cb, 1442 dump_val_cb_t dump_val_cb, 1432 1443 enum dict_avp_basetype datatype, 1433 1444 char * type_name, 1434 1445 char * const_name, 1435 1446 int indent, 1436 char **outstr,1437 size_t *offset,1438 size_t *outlen,1439 1447 int header) 1440 1448 { 1441 1449 if (header) { 1442 1450 /* Header for all AVP values dumps: */ 1443 CHECK_ FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "value ", INOBJHDRVAL));1451 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, INOBJHDR "value ", INOBJHDRVAL), return NULL); 1444 1452 1445 1453 /* If the type is provided, write it */ 1446 1454 if (type_name) { 1447 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "t: '%s' ", type_name));1455 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "t: '%s' ", type_name), return NULL); 1448 1456 } 1449 1457 1450 1458 /* Always give the base datatype anyway */ 1451 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "(%s) ", type_base_name[datatype]));1459 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(%s) ", type_base_name[datatype]), return NULL); 1452 1460 1453 1461 /* Now, the value */ 1454 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "v: "));1462 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "v: "), return NULL); 1455 1463 } 1456 1464 if (const_name) { 1457 CHECK_ FCT( dump_add_str(outstr, offset, outlen, "'%s' (", const_name));1465 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s' (", const_name), return NULL); 1458 1466 } 1459 1467 if (dump_val_cb) { 1460 char * str; 1461 CHECK_MALLOC_DO( str = (*dump_val_cb)(avp_value), dump_add_str(outstr, offset, outlen, "(dump failed)") ); 1462 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s", str) ); 1463 free(str); 1468 CHECK_MALLOC_DO( (*dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), fd_dump_extend( FD_DUMP_STD_PARAMS, "(dump failed)")); 1464 1469 } else { 1465 CHECK_ FCT( (*def_dump_val_cb)(avp_value, outstr, offset, outlen));1470 CHECK_MALLOC_DO( (*def_dump_val_cb)( FD_DUMP_STD_PARAMS, avp_value), return NULL); 1466 1471 } 1467 1472 if (const_name) { 1468 CHECK_ FCT( dump_add_str(outstr, offset, outlen, ")"));1473 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, ")"), return NULL); 1469 1474 } 1470 1475 1471 1476 /* Done! */ 1472 return 0;1477 return *buf; 1473 1478 } 1474 1479 1475 1480 /* Dump the value of an AVP of known type into the returned str */ 1476 int fd_dict_dump_avp_value(union avp_value *avp_value, struct dict_object * model, int indent, char **outstr, size_t *offset, size_t *outlen, int header)1477 { 1478 char * (*dump_val_cb)(union avp_value *avp_value) = NULL;1481 DECLARE_FD_DUMP_PROTOTYPE(fd_dict_dump_avp_value, union avp_value *avp_value, struct dict_object * model, int indent, int header) 1482 { 1483 DECLARE_FD_DUMP_PROTOTYPE((*dump_val_cb), union avp_value *avp_value) = NULL; 1479 1484 struct dict_object * type = NULL; 1480 1485 char * type_name = NULL; 1481 1486 char * const_name = NULL; 1487 size_t o = 0; 1488 1489 if (!offset) 1490 offset = &o; 1482 1491 1483 1492 /* Check the parameters are correct */ 1484 CHECK_PARAMS ( avp_value && verify_object(model) && (model->type == DICT_AVP));1493 CHECK_PARAMS_DO( avp_value && verify_object(model) && (model->type == DICT_AVP), return NULL ); 1485 1494 1486 1495 /* Get the type definition of this AVP */ … … 1502 1511 /* bypass checks */ 1503 1512 if ((search_enumval( type->dico, ENUMVAL_BY_STRUCT, &request, &enumval ) == 0) && (enumval)) { 1504 /* We found a co sntant, get its name */1513 /* We found a constant, get its name */ 1505 1514 const_name = enumval->data.enumval.enum_name; 1506 1515 } … … 1508 1517 1509 1518 /* And finally, dump the value */ 1510 CHECK_ FCT( dump_avp_val(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, outstr, offset, outlen, header));1511 return 0;1519 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 ); 1520 return *buf; 1512 1521 } 1513 1522 … … 1574 1583 switch (dict_obj_info[type].parent) { 1575 1584 case 0: /* parent is forbidden */ 1576 CHECK_PARAMS ( parent == NULL);1585 CHECK_PARAMS_DO( parent == NULL, goto error_param ); 1577 1586 1578 1587 case 1: /* parent is optional */ … … 1581 1590 1582 1591 case 2: /* parent is mandatory */ 1583 CHECK_PARAMS ( verify_object(parent));1592 CHECK_PARAMS_DO( verify_object(parent), goto error_param ); 1584 1593 1585 1594 if (type == DICT_RULE ) { /* Special case : grouped AVP or Command parents are allowed */ 1586 CHECK_PARAMS ( (parent->type == DICT_COMMAND )1587 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ) );1595 CHECK_PARAMS_DO( (parent->type == DICT_COMMAND ) 1596 || ( (parent->type == DICT_AVP) && (parent->data.avp.avp_basetype == AVP_TYPE_GROUPED ) ), goto error_param ); 1588 1597 } else { 1589 CHECK_PARAMS ( parent->type == dict_obj_info[type].parenttype);1598 CHECK_PARAMS_DO( parent->type == dict_obj_info[type].parenttype, goto error_param ); 1590 1599 } 1591 1600 } … … 1594 1603 if (type == DICT_AVP) { 1595 1604 CHECK_FCT_DO( fd_dict_search( dict, DICT_VENDOR, VENDOR_BY_ID, &(((struct dict_avp_data *)data)->avp_vendor), (void*)&vendor, ENOENT ), 1596 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); return EINVAL; } );1605 { TRACE_DEBUG(INFO, "Unable to find vendor '%d' referenced in the AVP data", ((struct dict_avp_data *)data)->avp_vendor); goto error_param; } ); 1597 1606 1598 1607 /* Also check if a parent is provided, that the type are the same */ 1599 1608 if (parent) { 1600 CHECK_PARAMS ( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype);1609 CHECK_PARAMS_DO( parent->data.type.type_base == ((struct dict_avp_data *)data)->avp_basetype, goto error_param ); 1601 1610 } 1602 1611 } … … 1604 1613 /* For RULE object, we must also check that the "avp" referenced exists */ 1605 1614 if (type == DICT_RULE) { 1606 CHECK_PARAMS ( verify_object(((struct dict_rule_data *)data)->rule_avp));1607 CHECK_PARAMS ( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP);1615 CHECK_PARAMS_DO( verify_object(((struct dict_rule_data *)data)->rule_avp), goto error_param ); 1616 CHECK_PARAMS_DO( ((struct dict_rule_data *)data)->rule_avp->type == DICT_AVP, goto error_param ); 1608 1617 } 1609 1618 1610 1619 /* For COMMAND object, check that the 'R' flag is fixed */ 1611 1620 if (type == DICT_COMMAND) { 1612 CHECK_PARAMS ( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST);1621 CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); 1613 1622 } 1614 1623 1615 1624 /* We have to check that the new values are not equal to the sentinels */ 1616 1625 if (type == DICT_VENDOR) { 1617 CHECK_PARAMS ( ((struct dict_vendor_data *)data)->vendor_id != 0);1626 CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); 1618 1627 } 1619 1628 if (type == DICT_APPLICATION) { 1620 CHECK_PARAMS ( ((struct dict_application_data *)data)->application_id != 0);1629 CHECK_PARAMS_DO( ((struct dict_application_data *)data)->application_id != 0, goto error_param ); 1621 1630 } 1622 1631 … … 1718 1727 return 0; 1719 1728 1729 error_param: 1730 ret = EINVAL; 1731 goto all_errors; 1732 1720 1733 error_unlock: 1721 1734 CHECK_POSIX_DO( pthread_rwlock_unlock(&dict->dict_lock), /* continue */ ); … … 1728 1741 if (fd_os_cmp(locref->data.vendor.vendor_name, locref->datastr_len, 1729 1742 new->data.vendor.vendor_name, new->datastr_len)) { 1730 TRACE_DEBUG( FULL, "Conflicting vendor name");1743 TRACE_DEBUG(INFO, "Conflicting vendor name: %s", new->data.vendor.vendor_name); 1731 1744 break; 1732 1745 } … … 1866 1879 break; 1867 1880 } 1868 if (ret) { 1869 TRACE_DEBUG(INFO, "An existing object with different non-key data was found: EEXIST"); 1870 if (TRACE_BOOL(INFO)) { 1871 fd_log_debug("New object to insert:"); 1872 dump_object(new, 0, 0, 3); 1873 fd_log_debug("Object already in dictionary:"); 1874 dump_object(locref, 0, 0 , 3); 1875 } 1876 } else { 1881 if (!ret) { 1877 1882 TRACE_DEBUG(FULL, "An existing object with the same data was found, ignoring the error..."); 1878 1883 } 1879 1884 if (ref) 1880 1885 *ref = locref; 1881 } else { 1882 CHECK_FCT_DO( ret, ); /* log the error */ 1883 } 1884 1886 } 1887 all_errors: 1888 if (ret != 0) { 1889 char * buf = NULL; 1890 size_t len = 0; 1891 1892 CHECK_MALLOC( dict_obj_info[CHECK_TYPE(type) ? type : 0].dump_data(&buf, &len, NULL, data) ); 1893 TRACE_DEBUG(INFO, "An error occurred while adding the following data in the dictionary: %s", buf); 1894 1895 if (ret == EEXIST) { 1896 CHECK_MALLOC( dump_object(&buf, &len, NULL, locref, 0, 0, 0) ); 1897 TRACE_DEBUG(INFO, "Conflicting entry in the dictionary: %s", buf); 1898 } 1899 free(buf); 1900 } 1885 1901 error_free: 1886 1902 free(new);
Note: See TracChangeset
for help on using the changeset viewer.