| 402 | |
| 403 | |
| 404 | static int dm_pack_avps(void *root, struct list_head *subavps) |
| 405 | { |
| 406 | struct list_head *it; |
| 407 | struct dm_avp *dm_avp; |
| 408 | struct avp *subavp; |
| 409 | union avp_value val; |
| 410 | |
| 411 | list_for_each (it, subavps) { |
| 412 | struct dict_object *obj; |
| 413 | struct dict_avp_data savp_data; |
| 414 | |
| 415 | dm_avp = list_entry(it, struct dm_avp, list); |
| 416 | |
| 417 | /* each AVP must be recognized, otherwise we abort the request */ |
| 418 | FD_CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, dm_avp->name.s, &obj); |
| 419 | FD_CHECK(fd_msg_avp_new(obj, 0, &subavp)); |
| 420 | FD_CHECK(fd_dict_getval(obj, &savp_data)); |
| 421 | |
| 422 | memset(&val, 0, sizeof val); |
| 423 | |
| 424 | if (savp_data.avp_basetype == AVP_TYPE_GROUPED) { |
| 425 | if (dm_pack_avps(subavp, &dm_avp->subavps) != 0) { |
| 426 | LM_ERR("failed to fill in grouped sub-AVP %s (%u)\n", |
| 427 | savp_data.avp_name, savp_data.avp_code); |
| 428 | return -1; |
| 429 | } |
| 430 | LM_DBG("appending AVP: %s (%u): grouped\n", |
| 431 | savp_data.avp_name, savp_data.avp_code); |
| 432 | } else if (savp_data.avp_basetype == AVP_TYPE_OCTETSTRING) { |
| 433 | val.os = dm_avp->value.os; |
| 434 | LM_DBG("appending AVP: %s (%u): %d str(%.*s)\n", |
| 435 | savp_data.avp_name, savp_data.avp_code,(int)val.os.len, |
| 436 | (int)val.os.len, val.os.data); |
| 437 | FD_CHECK(fd_msg_avp_setvalue(subavp, &val)); |
| 438 | } else { |
| 439 | val = dm_avp->value; |
| 440 | |
| 441 | LM_DBG("appending AVP: %s (%u): numeric(%u)\n", |
| 442 | savp_data.avp_name, savp_data.avp_code, val.i32); |
| 443 | FD_CHECK(fd_msg_avp_setvalue(subavp, &val)); |
| 444 | } |
| 445 | |
| 446 | FD_CHECK(fd_msg_avp_add(root, MSG_BRW_LAST_CHILD, subavp)); |
| 447 | } |
| 448 | |
| 449 | return 0; |
| 450 | } |
| 451 | |
| 452 | |
| 453 | static int dm_send_custom_req(struct dm_message *msg) |
no test coverage detected