| 1880 | } |
| 1881 | |
| 1882 | int dm_build_avps(struct list_head *out_avps, cJSON *array) |
| 1883 | { |
| 1884 | cJSON *_avp, *avp; |
| 1885 | struct dict_avp_data dm_avp; |
| 1886 | struct dict_object *obj; |
| 1887 | char *name; |
| 1888 | unsigned int code, vendor; |
| 1889 | str st; |
| 1890 | struct dict_avp_enc_f *func; |
| 1891 | int ret; |
| 1892 | |
| 1893 | for (_avp = array; _avp; _avp = _avp->next) { |
| 1894 | if (_avp->type != cJSON_Object) { |
| 1895 | LM_ERR("bad JSON type in Grouped AVP: sub-AVPs must be Objects\n"); |
| 1896 | return -1; |
| 1897 | } |
| 1898 | |
| 1899 | avp = _avp->child; |
| 1900 | |
| 1901 | // TODO: allow dict too, e.g. maybe for setting a non-zero VendorId?! |
| 1902 | if (!(avp->type & (cJSON_String|cJSON_Number|cJSON_Array))) { |
| 1903 | LM_ERR("bad AVP value: only String allowed (AVP name: %s)\n", avp->string); |
| 1904 | goto error; |
| 1905 | } |
| 1906 | |
| 1907 | init_str(&st, avp->string); |
| 1908 | if (str2int(&st, &code) == 0) { |
| 1909 | |
| 1910 | LM_DBG("AVP:: searching AVP by int: %d\n", code); |
| 1911 | FD_CHECK(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, |
| 1912 | &code, &obj, ENOENT)); |
| 1913 | FD_CHECK(fd_dict_getval(obj, &dm_avp)); |
| 1914 | |
| 1915 | name = dm_avp.avp_name; |
| 1916 | vendor = dm_avp.avp_vendor; |
| 1917 | } else { |
| 1918 | LM_DBG("AVP:: searching AVP by string: %s\n", avp->string); |
| 1919 | |
| 1920 | FD_CHECK(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, |
| 1921 | avp->string, &obj, ENOENT)); |
| 1922 | FD_CHECK(fd_dict_getval(obj, &dm_avp)); |
| 1923 | |
| 1924 | name = avp->string; |
| 1925 | code = dm_avp.avp_code; |
| 1926 | vendor = dm_avp.avp_vendor; |
| 1927 | } |
| 1928 | |
| 1929 | aaa_map my_avp = {.name = name}; |
| 1930 | func = dm_enc_get(code, vendor); |
| 1931 | |
| 1932 | if (func && func->enc_func) { |
| 1933 | LM_DBG("dbg::: AVP %d (name: '%s', encoded)\n", code, name); |
| 1934 | ret = func->enc_func(_avp->child, &dm_avp, vendor, &st); |
| 1935 | if (ret < 0) { |
| 1936 | LM_ERR("could not encode %d/%d\n", code, vendor); |
| 1937 | goto error; |
| 1938 | } else if (ret == 0) { |
| 1939 | ret = _dm_avp_add(NULL, out_avps, &my_avp, st.s, st.len, 0); |
no test coverage detected