mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
6.8 KiB
294 lines
6.8 KiB
/**
|
|
* Copyright (C) 2013 Flowroute LLC (flowroute.com)
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* This file is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
*
|
|
* This file is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <jansson.h>
|
|
|
|
#include "../../mod_fix.h"
|
|
#include "../../lvalue.h"
|
|
|
|
#include "jansson_path.h"
|
|
#include "jansson_funcs.h"
|
|
#include "jansson_utils.h"
|
|
|
|
int janssonmod_get(struct sip_msg* msg, char* path_in, char* src_in, char* dst)
|
|
{
|
|
str src_s;
|
|
str path_s;
|
|
pv_spec_t *dst_pv;
|
|
pv_value_t dst_val;
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)src_in, &src_s) != 0) {
|
|
ERR("cannot get json string value\n");
|
|
return -1;
|
|
}
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)path_in, &path_s) != 0) {
|
|
ERR("cannot get path string value\n");
|
|
return -1;
|
|
}
|
|
|
|
dst_pv = (pv_spec_t *)dst;
|
|
|
|
json_t* json = NULL;
|
|
json_error_t parsing_error;
|
|
|
|
json = json_loads(src_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
|
|
|
|
if(!json) {
|
|
ERR("failed to parse: %.*s\n", src_s.len, src_s.s);
|
|
ERR("json error at line %d: %s\n",
|
|
parsing_error.line, parsing_error.text);
|
|
goto fail;
|
|
}
|
|
|
|
char* path = path_s.s;
|
|
|
|
json_t* v = json_path_get(json, path);
|
|
if(!v) {
|
|
goto fail;
|
|
}
|
|
|
|
char* freeme = NULL;
|
|
|
|
if(jansson_to_val(&dst_val, &freeme, v)<0) goto fail;
|
|
|
|
dst_pv->setf(msg, &dst_pv->pvp, (int)EQ_T, &dst_val);
|
|
|
|
if(freeme!=NULL) {
|
|
free(freeme);
|
|
}
|
|
|
|
json_decref(json);
|
|
return 1;
|
|
|
|
fail:
|
|
json_decref(json);
|
|
return -1;
|
|
}
|
|
|
|
#define STR_EQ_STATIC(a,b) ((a.len == sizeof(b)-1) && (strncmp(a.s, b, sizeof(b)-1)==0))
|
|
|
|
int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
|
|
char* path_in, char* value_in, char* result_in)
|
|
{
|
|
str type_s;
|
|
str value_s;
|
|
str path_s;
|
|
|
|
pv_spec_t* result_pv;
|
|
pv_value_t result_val;
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)type_in, &type_s) != 0){
|
|
ERR("cannot get type string value\n");
|
|
return -1;
|
|
}
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)value_in, &value_s) != 0){
|
|
ERR("cannot get value string\n");
|
|
return -1;
|
|
}
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)path_in, &path_s) != 0){
|
|
ERR("cannot get path string value\n");
|
|
return -1;
|
|
}
|
|
|
|
result_pv = (pv_spec_t *)result_in;
|
|
|
|
if(pv_get_spec_value(msg, result_pv, &result_val)!=0
|
|
|| result_val.flags != PV_VAL_STR) {
|
|
result_val.flags = PV_VAL_STR;
|
|
result_val.rs.s = "{}";
|
|
result_val.rs.len = strlen("{}");
|
|
}
|
|
|
|
/*
|
|
ALERT("type is: %.*s\n", type_s.len, type_s.s);
|
|
ALERT("path is: %.*s\n", path_s.len, path_s.s);
|
|
ALERT("value is: %.*s\n", value_s.len, value_s.s);
|
|
ALERT("result is: %.*s\n", result_val.rs.len, result_val.rs.s);
|
|
*/
|
|
|
|
char* result = result_val.rs.s;
|
|
|
|
json_t* result_json = NULL;
|
|
json_t* value = NULL;
|
|
char* freeme = NULL;
|
|
json_error_t parsing_error = {0};
|
|
char* endptr;
|
|
|
|
/* check the type */
|
|
if(STR_EQ_STATIC(type_s, "object") || STR_EQ_STATIC(type_s, "obj")){
|
|
value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
|
|
if(value && !json_is_object(value)) {
|
|
ERR("value to add is not an object - \"%s\"\n", path_s.s);
|
|
goto fail;
|
|
}
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "array")) {
|
|
value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
|
|
if(value && !json_is_array(value)) {
|
|
ERR("value to add is not an array - \"%s\"\n", path_s.s);
|
|
goto fail;
|
|
}
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "string")
|
|
|| STR_EQ_STATIC(type_s, "str")) {
|
|
value = json_string(value_s.s);
|
|
if(!value || !json_is_string(value)) {
|
|
ERR("value to add is not a string - \"%s\"\n", path_s.s);
|
|
goto fail;
|
|
}
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "integer")
|
|
|| STR_EQ_STATIC(type_s, "int")) {
|
|
long long i = strtoll(value_s.s, &endptr, 10);
|
|
if(*endptr != '\0') {
|
|
ERR("parsing int failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
|
|
goto fail;
|
|
}
|
|
value = json_integer(i);
|
|
if(!value || !json_is_integer(value)) {
|
|
ERR("value to add is not an integer \"%s\"\n", path_s.s);
|
|
goto fail;
|
|
}
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "real")) {
|
|
double d = strtod(value_s.s, &endptr);
|
|
if(*endptr != '\0') {
|
|
ERR("parsing real failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
|
|
goto fail;
|
|
}
|
|
value = json_real(d);
|
|
if(!value || !json_is_real(value)) {
|
|
ERR("value to add is not a real \"%s\"\n", path_s.s);
|
|
goto fail;
|
|
}
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "true")) {
|
|
value = json_true();
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "false")) {
|
|
value = json_false();
|
|
|
|
}else if(STR_EQ_STATIC(type_s, "null")) {
|
|
value = json_null();
|
|
|
|
} else {
|
|
ERR("unrecognized input type\n");
|
|
goto fail;
|
|
}
|
|
|
|
if(!value) {
|
|
ERR("parsing failed for \"%s\"\n", value_s.s);
|
|
ERR("value error at line %d: %s\n",
|
|
parsing_error.line, parsing_error.text);
|
|
goto fail;
|
|
}
|
|
|
|
char* path = path_s.s;
|
|
|
|
result_json = json_loads(result, JSON_REJECT_DUPLICATES, &parsing_error);
|
|
|
|
if(!result_json) {
|
|
ERR("result has json error at line %d: %s\n",
|
|
parsing_error.line, parsing_error.text);
|
|
goto fail;
|
|
}
|
|
|
|
if(json_path_set(result_json, path, value, append)<0) {
|
|
goto fail;
|
|
}
|
|
|
|
if(jansson_to_val(&result_val, &freeme, result_json)<0) goto fail;
|
|
|
|
result_pv->setf(msg, &result_pv->pvp, (int)EQ_T, &result_val);
|
|
|
|
if(freeme) free(freeme);
|
|
json_decref(result_json);
|
|
return 1;
|
|
|
|
fail:
|
|
if(freeme) free(freeme);
|
|
json_decref(result_json);
|
|
return -1;
|
|
}
|
|
|
|
int janssonmod_array_size(struct sip_msg* msg, char* path_in, char* src_in, char* dst)
|
|
{
|
|
str src_s;
|
|
str path_s;
|
|
pv_spec_t *dst_pv;
|
|
pv_value_t dst_val;
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)src_in, &src_s) != 0) {
|
|
ERR("cannot get json string value\n");
|
|
return -1;
|
|
}
|
|
|
|
if (fixup_get_svalue(msg, (gparam_p)path_in, &path_s) != 0) {
|
|
ERR("cannot get path string value\n");
|
|
return -1;
|
|
}
|
|
|
|
dst_pv = (pv_spec_t *)dst;
|
|
|
|
json_t* json = NULL;
|
|
json_error_t parsing_error;
|
|
|
|
json = json_loads(src_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
|
|
|
|
if(!json) {
|
|
ERR("json error at line %d: %s\n",
|
|
parsing_error.line, parsing_error.text);
|
|
goto fail;
|
|
}
|
|
|
|
char* path = path_s.s;
|
|
|
|
json_t* v = json_path_get(json, path);
|
|
if(!v) {
|
|
ERR("failed to find %s in json\n", path);
|
|
goto fail;
|
|
}
|
|
|
|
if(!json_is_array(v)) {
|
|
ERR("value at %s is not an array\n", path);
|
|
goto fail;
|
|
}
|
|
|
|
int size = json_array_size(v);
|
|
dst_val.ri = size;
|
|
dst_val.flags = PV_TYPE_INT|PV_VAL_INT;
|
|
|
|
dst_pv->setf(msg, &dst_pv->pvp, (int)EQ_T, &dst_val);
|
|
|
|
json_decref(json);
|
|
return 1;
|
|
|
|
fail:
|
|
json_decref(json);
|
|
return -1;
|
|
}
|