| 1795 | |
| 1796 | |
| 1797 | int _dm_avp_add(aaa_conn *_, struct list_head *avp_arr, aaa_map *avp, void *val, |
| 1798 | int val_length, int vendor) |
| 1799 | { |
| 1800 | struct { |
| 1801 | struct dm_avp davp; |
| 1802 | char buf[0]; |
| 1803 | } *wrap; |
| 1804 | int len; |
| 1805 | |
| 1806 | if (!avp || !avp->name || val_length < AAA_TYPE_GROUPED) |
| 1807 | return -1; |
| 1808 | len = strlen(avp->name); |
| 1809 | |
| 1810 | wrap = shm_malloc(sizeof *wrap + len + 1 + |
| 1811 | (val_length < 0 ? 0 : val_length) + 1); |
| 1812 | if (!wrap) { |
| 1813 | LM_ERR("oom\n"); |
| 1814 | return -1; |
| 1815 | } |
| 1816 | |
| 1817 | memset(&wrap->davp, 0, sizeof wrap->davp); |
| 1818 | INIT_LIST_HEAD(&wrap->davp.subavps); |
| 1819 | |
| 1820 | wrap->davp.name.s = wrap->buf; |
| 1821 | wrap->davp.name.len = len; |
| 1822 | strcpy(wrap->buf, avp->name); |
| 1823 | wrap->davp.vendor_id = vendor; |
| 1824 | |
| 1825 | if (val_length >= 0) { |
| 1826 | wrap->davp.value_type = AAA_TYPE_OCTETSTRING; |
| 1827 | |
| 1828 | wrap->davp.value.os.data = (uint8_t *)(wrap->buf + len + 1); |
| 1829 | wrap->davp.value.os.len = val_length; |
| 1830 | memcpy(wrap->davp.value.os.data, val, val_length); |
| 1831 | wrap->davp.value.os.data[val_length] = '\0'; |
| 1832 | } else if (val_length == AAA_TYPE_GROUPED) { |
| 1833 | wrap->davp.value_type = val_length; |
| 1834 | |
| 1835 | if (dm_build_avps(&wrap->davp.subavps, (cJSON *)val) != 0) { |
| 1836 | LM_ERR("failed to build sub-AVP list\n"); |
| 1837 | shm_free(wrap); |
| 1838 | return -1; |
| 1839 | } |
| 1840 | } else { |
| 1841 | wrap->davp.value_type = val_length; |
| 1842 | |
| 1843 | switch (val_length) { |
| 1844 | case AAA_TYPE_INT32: |
| 1845 | wrap->davp.value.i32 = (int32_t)*(double *)val; |
| 1846 | break; |
| 1847 | |
| 1848 | case AAA_TYPE_INT64: |
| 1849 | wrap->davp.value.i64 = (int64_t)*(double *)val; |
| 1850 | break; |
| 1851 | |
| 1852 | case AAA_TYPE_UINT32: |
| 1853 | wrap->davp.value.u32 = (uint32_t)*(double *)val; |
| 1854 | break; |
no test coverage detected