예제 #1
0
int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level)
{
	char *output = NULL;
	srjson_doc_t jdoc;

	srjson_InitDoc(&jdoc, NULL);
	if(jdoc.root==NULL)
	{
		jdoc.root = srjson_CreateObject(&jdoc);
		if(jdoc.root==NULL)
		{
			LM_ERR("cannot create json root\n");
			goto error;
		}
	}

	if(dbg_get_json(msg, mask, &jdoc, jdoc.root)<0) goto error;
	output = srjson_PrintUnformatted(&jdoc, jdoc.root);
	if(output==NULL)
	{
		LM_ERR("cannot print json doc\n");
		srjson_DestroyDoc(&jdoc);
	}
	LOG(level, "%s\n", output);
	jdoc.free_fn(output);
	srjson_DestroyDoc(&jdoc);
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	return -1;
}
예제 #2
0
int usrloc_dmq_send_contact(ucontact_t* ptr, str aor, int action, dmq_node_t* node) {
	srjson_doc_t jdoc;
	srjson_InitDoc(&jdoc, NULL);

	int flags;

	jdoc.root = srjson_CreateObject(&jdoc);
	if(jdoc.root==NULL) {
		LM_ERR("cannot create json root\n");
		goto error;
	}

	flags = ptr->flags;
	flags &= ~FL_RPL;

	srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action);

	srjson_AddStrToObject(&jdoc, jdoc.root, "aor", aor.s, aor.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "ruid", ptr->ruid.s, ptr->ruid.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "c", ptr->c.s, ptr->c.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "received", ptr->received.s, ptr->received.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "path", ptr->path.s, ptr->path.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "callid", ptr->callid.s, ptr->callid.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "user_agent", ptr->user_agent.s, ptr->user_agent.len);
	srjson_AddStrToObject(&jdoc, jdoc.root, "instance", ptr->instance.s, ptr->instance.len);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "expires", ptr->expires);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "cseq", ptr->cseq);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "flags", flags);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "cflags", ptr->cflags);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "q", ptr->q);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "last_modified", ptr->last_modified);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "methods", ptr->methods);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "reg_id", ptr->reg_id);

	jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root);
	if(jdoc.buf.s==NULL) {
		LM_ERR("unable to serialize data\n");
		goto error;
	}
	jdoc.buf.len = strlen(jdoc.buf.s);

	LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s);
	if (usrloc_dmq_send(&jdoc.buf, node)!=0) {
		goto error;
	}

	jdoc.free_fn(jdoc.buf.s);
	jdoc.buf.s = NULL;
	srjson_DestroyDoc(&jdoc);
	return 0;

error:
	if(jdoc.buf.s!=NULL) {
		jdoc.free_fn(jdoc.buf.s);
		jdoc.buf.s = NULL;
	}
	srjson_DestroyDoc(&jdoc);
	return -1;
}
예제 #3
0
int ht_dmq_replicate_action(ht_dmq_action_t action, str* htname, str* cname, int type, int_str* val, int mode) {

    srjson_doc_t jdoc;

    LM_DBG("replicating action to dmq peers...\n");

    srjson_InitDoc(&jdoc, NULL);

    jdoc.root = srjson_CreateObject(&jdoc);
    if(jdoc.root==NULL) {
        LM_ERR("cannot create json root\n");
        goto error;
    }

    srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action);
    srjson_AddStrToObject(&jdoc, jdoc.root, "htname", htname->s, htname->len);
    if (cname!=NULL) {
        srjson_AddStrToObject(&jdoc, jdoc.root, "cname", cname->s, cname->len);
    }

    if (action==HT_DMQ_SET_CELL || action==HT_DMQ_SET_CELL_EXPIRE || action==HT_DMQ_RM_CELL_RE) {
        srjson_AddNumberToObject(&jdoc, jdoc.root, "type", type);
        if (type&AVP_VAL_STR) {
            srjson_AddStrToObject(&jdoc, jdoc.root, "strval", val->s.s, val->s.len);
        } else {
            srjson_AddNumberToObject(&jdoc, jdoc.root, "intval", val->n);
        }
    }

    srjson_AddNumberToObject(&jdoc, jdoc.root, "mode", mode);

    jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root);
    if(jdoc.buf.s!=NULL) {
        jdoc.buf.len = strlen(jdoc.buf.s);
        LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s);
        if (ht_dmq_broadcast(&jdoc.buf)!=0) {
            goto error;
        }
        jdoc.free_fn(jdoc.buf.s);
        jdoc.buf.s = NULL;
    } else {
        LM_ERR("unable to serialize data\n");
        goto error;
    }

    srjson_DestroyDoc(&jdoc);
    return 0;

error:
    if(jdoc.buf.s!=NULL) {
        jdoc.free_fn(jdoc.buf.s);
        jdoc.buf.s = NULL;
    }
    srjson_DestroyDoc(&jdoc);
    return -1;
}
예제 #4
0
int rtjson_init_routes(sip_msg_t *msg, str *rdoc)
{
	sr_xavp_t *xavp=NULL;
	str xname;
	sr_xval_t xval;
	srjson_doc_t tdoc;

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, rdoc->s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", rdoc->s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	/* basic validation */

	srjson_DestroyDoc(&tdoc);

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_INT;
	xval.v.i = 0;
	xname.s = "idx";
	xname.len = 3;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_STR;
	xval.v.s = *rdoc;
	xname.s = "json";
	xname.len = 4;
	if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
		goto error;
	}

	memset(&xval, 0, sizeof(sr_xval_t));
	xval.type = SR_XTYPE_XAVP;
	xval.v.xavp = xavp;
	if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) {
		goto error;
	}

	return 0;

error:
	if(xavp) xavp_destroy_list(&xavp);
	return -1;
}
예제 #5
0
int usrloc_dmq_request_sync() {
	srjson_doc_t jdoc;

	if(_dmq_usrloc_sync==0)
		return 0;

	LM_DBG("requesting sync from dmq peers\n");
	srjson_InitDoc(&jdoc, NULL);

	jdoc.root = srjson_CreateObject(&jdoc);
	if(jdoc.root==NULL) {
		LM_ERR("cannot create json root\n");
		goto error;
	}

	srjson_AddNumberToObject(&jdoc, jdoc.root, "action", DMQ_SYNC);
	jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root);
	if(jdoc.buf.s==NULL) {
		LM_ERR("unable to serialize data\n");
		goto error;
	}
	jdoc.buf.len = strlen(jdoc.buf.s);
	LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s);
	if (usrloc_dmq_send(&jdoc.buf, 0)!=0) {
		goto error;
	}

	jdoc.free_fn(jdoc.buf.s);
	jdoc.buf.s = NULL;
	srjson_DestroyDoc(&jdoc);
	return 0;

error:
	if(jdoc.buf.s!=NULL) {
		jdoc.free_fn(jdoc.buf.s);
		jdoc.buf.s = NULL;
	}
	srjson_DestroyDoc(&jdoc);
	return -1;
}
예제 #6
0
파일: dlg_dmq.c 프로젝트: SipSeb/kamailio
/**
* @brief ht dmq callback
*/
int dlg_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	dlg_cell_t *dlg;
	int unref = 0;
	int ret;
	srjson_doc_t jdoc, prof_jdoc;
	srjson_t *it = NULL;

	dlg_dmq_action_t action = DLG_DMQ_NONE;
	dlg_iuid_t iuid;
	str profiles = {0, 0}, callid = {0, 0}, tag1 = {0,0}, tag2 = {0,0},
		contact1 = {0,0}, contact2 = {0,0}, k={0,0}, v={0,0};
	str cseq1 = {0,0}, cseq2 = {0,0}, route_set1 = {0,0}, route_set2 = {0,0},
		from_uri = {0,0}, to_uri = {0,0}, req_uri = {0,0};
	unsigned int init_ts = 0, start_ts = 0, lifetime = 0;
	unsigned int state = 1;
	srjson_t *vj;

	/* received dmq message */
	LM_DBG("dmq message received\n");

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid2;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid2;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	/* parse body */
	LM_DBG("body: %.*s\n", body.len, body.s);

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;

	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if ((it->string == NULL) || (strcmp(it->string, "vars")==0)) continue;

		LM_DBG("found field: %s\n", it->string);

		if (strcmp(it->string, "action")==0) {
			action = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_entry")==0) {
			iuid.h_entry = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "h_id")==0) {
			iuid.h_id = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "init_ts")==0) {
			init_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "start_ts")==0) {
			start_ts = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "state")==0) {
			state = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "lifetime")==0) {
			lifetime = SRJSON_GET_UINT(it);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "profiles")==0) {
			profiles.s = it->valuestring;
			profiles.len = strlen(profiles.s);
		} else if (strcmp(it->string, "tag1")==0) {
			tag1.s = it->valuestring;
			tag1.len = strlen(tag1.s);
		} else if (strcmp(it->string, "tag2")==0) {
			tag2.s = it->valuestring;
			tag2.len = strlen(tag2.s);
		} else if (strcmp(it->string, "cseq1")==0) {
			cseq1.s = it->valuestring;
			cseq1.len = strlen(cseq1.s);
		} else if (strcmp(it->string, "cseq2")==0) {
			cseq2.s = it->valuestring;
			cseq2.len = strlen(cseq2.s);
		} else if (strcmp(it->string, "route_set1")==0) {
			route_set1.s = it->valuestring;
			route_set1.len = strlen(route_set1.s);
		} else if (strcmp(it->string, "route_set2")==0) {
			route_set2.s = it->valuestring;
			route_set2.len = strlen(route_set2.s);
		} else if (strcmp(it->string, "contact1")==0) {
			contact1.s = it->valuestring;
			contact1.len = strlen(contact1.s);
		} else if (strcmp(it->string, "contact2")==0) {
			contact2.s = it->valuestring;
			contact2.len = strlen(contact2.s);
		} else if (strcmp(it->string, "from_uri")==0) {
			from_uri.s = it->valuestring;
			from_uri.len = strlen(from_uri.s);
		} else if (strcmp(it->string, "to_uri")==0) {
			to_uri.s = it->valuestring;
			to_uri.len = strlen(to_uri.s);
		} else if (strcmp(it->string, "req_uri")==0) {
			req_uri.s = it->valuestring;
			req_uri.len = strlen(req_uri.s);
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}

	dlg = dlg_get_by_iuid(&iuid);
	if (dlg) {
		LM_DBG("found dialog [%u:%u] at %p\n", iuid.h_entry, iuid.h_id, dlg);
		unref++;
	}

	switch(action) {
		case DLG_DMQ_UPDATE:
			LM_DBG("Updating dlg [%u:%u] with callid [%.*s]\n", iuid.h_entry, iuid.h_id,
					callid.len, callid.s);
			if (!dlg) {
				dlg = build_new_dlg(&callid, &from_uri, &to_uri, &tag1, &req_uri);
				if (!dlg) {
					LM_ERR("failed to build new dialog\n");
					goto error;
				}

				if(dlg->h_entry != iuid.h_entry){
					LM_ERR("inconsistent hash data from peer: "
						"make sure all Kamailio's use the same hash size\n");
					shm_free(dlg);
					goto error;
				}

				/* link the dialog */
				link_dlg(dlg, 0, 0);
				dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
				/* override generated h_id */
				dlg->h_id = iuid.h_id;
				/* prevent DB sync */
				dlg->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED);
				dlg->iflags |= DLG_IFLAG_DMQ_SYNC;
			} else {
				/* remove existing profiles */
				if (dlg->profile_links!=NULL) {
					destroy_linkers(dlg->profile_links);
					dlg->profile_links = NULL;
				}
			}

			dlg->init_ts = init_ts;
			dlg->start_ts = start_ts;

			vj = srjson_GetObjectItem(&jdoc, jdoc.root, "vars");
			if(vj!=NULL) {
				for(it=vj->child; it; it = it->next)
				{
					k.s = it->string;        k.len = strlen(k.s);
					v.s = it->valuestring;   v.len = strlen(v.s);
					set_dlg_variable(dlg, &k, &v);
				}
			}
			/* add profiles */
			if(profiles.s!=NULL) {
				srjson_InitDoc(&prof_jdoc, NULL);
				prof_jdoc.buf = profiles;
				dlg_json_to_profiles(dlg, &prof_jdoc);
				srjson_DestroyDoc(&prof_jdoc);
			}
			if (state == dlg->state) {
				break;
			}
			/* intentional fallthrough */

		case DLG_DMQ_STATE:
			if (!dlg) {
				LM_ERR("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			if (state < dlg->state) {
				LM_NOTICE("Ignoring backwards state change on dlg [%u:%u]"
						" with callid [%.*s] from state [%u] to state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
				break;
			}
			LM_DBG("State update dlg [%u:%u] with callid [%.*s] from state [%u]"
					" to state [%u]\n", iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state, state);
			switch (state) {
				case DLG_STATE_EARLY:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					break;
				case DLG_STATE_CONFIRMED:
					dlg->start_ts = start_ts;
					dlg->lifetime = lifetime;
					dlg_set_leg_info(dlg, &tag1, &route_set1, &contact1, &cseq1, 0);
					dlg_set_leg_info(dlg, &tag2, &route_set2, &contact2, &cseq2, 1);
					if (insert_dlg_timer( &dlg->tl, dlg->lifetime ) != 0) {
						LM_CRIT("Unable to insert dlg timer %p [%u:%u]\n",
							dlg, dlg->h_entry, dlg->h_id);
					} else {
						/* dialog pointer inserted in timer list */
						dlg_ref(dlg, 1);
					}
					break;
				case DLG_STATE_DELETED:
					if (dlg->state == DLG_STATE_CONFIRMED) {
						ret = remove_dialog_timer(&dlg->tl);
						if (ret == 0) {
							/* one extra unref due to removal from timer list */
							unref++;
						} else if (ret < 0) {
							LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
								dlg, dlg->h_entry, dlg->h_id);
						}
					}
					/* prevent DB sync */
					dlg->dflags |= DLG_FLAG_NEW;
					/* keep dialog around for a bit, to prevent out-of-order
					 * syncs to reestablish the dlg */
					dlg->init_ts = time(NULL);
					break;
				default:
					LM_ERR("unhandled state update to state %u\n", state);
					dlg_unref(dlg, unref);
					goto error;
			}
			dlg->state = state;
			break;

		case DLG_DMQ_RM:
			if (!dlg) {
				LM_DBG("dialog [%u:%u] not found\n", iuid.h_entry, iuid.h_id);
				goto error;
			}
			LM_DBG("Removed dlg [%u:%u] with callid [%.*s] int state [%u]\n",
					iuid.h_entry, iuid.h_id,
					dlg->callid.len, dlg->callid.s, dlg->state);
			if (dlg->state==DLG_STATE_CONFIRMED
					|| dlg->state==DLG_STATE_EARLY) {
				ret = remove_dialog_timer(&dlg->tl);
				if (ret == 0) {
					/* one extra unref due to removal from timer list */
					unref++;
				} else if (ret < 0) {
					LM_CRIT("unable to unlink the timer on dlg %p [%u:%u]\n",
						dlg, dlg->h_entry, dlg->h_id);
				}
			}
			/* prevent DB sync */
			dlg->dflags |= DLG_FLAG_NEW;
			unref++;
			break;

		case DLG_DMQ_SYNC:
			dmq_send_all_dlgs(0);
			break;

		case DLG_DMQ_NONE:
			break;
	}
	if (dlg && unref)
		dlg_unref(dlg, unref);

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
invalid2:
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
예제 #7
0
파일: dlg_dmq.c 프로젝트: SipSeb/kamailio
int dlg_dmq_replicate_action(dlg_dmq_action_t action, dlg_cell_t* dlg,
		int needlock, dmq_node_t *node ) {

	srjson_doc_t jdoc, prof_jdoc;
	dlg_var_t *var;

	LM_DBG("replicating action [%d] on [%u:%u] to dmq peers\n", action,
			dlg->h_entry, dlg->h_id);

	if (action == DLG_DMQ_UPDATE) {
		if (!node && (dlg->iflags & DLG_IFLAG_DMQ_SYNC)
				&& ((dlg->dflags & DLG_FLAG_CHANGED_PROF) == 0)) {
			LM_DBG("dlg not changed, no sync\n");
			return 1;
		}
	} else if ( (dlg->iflags & DLG_IFLAG_DMQ_SYNC) == 0 ) {
		LM_DBG("dlg not synced, no sync\n");
		return 1;
	}
	if (action == DLG_DMQ_STATE && (dlg->state != DLG_STATE_CONFIRMED
				&& dlg->state != DLG_STATE_DELETED
				&& dlg->state != DLG_STATE_EARLY)) {
		LM_DBG("not syncing state %u\n", dlg->state);
		return 1;
	}

	srjson_InitDoc(&jdoc, NULL);

	jdoc.root = srjson_CreateObject(&jdoc);
	if(jdoc.root==NULL) {
		LM_ERR("cannot create json root\n");
		goto error;
	}

	if (needlock)
		dlg_lock(d_table, &(d_table->entries[dlg->h_entry]));

	srjson_AddNumberToObject(&jdoc, jdoc.root, "action", action);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "h_entry", dlg->h_entry);
	srjson_AddNumberToObject(&jdoc, jdoc.root, "h_id", dlg->h_id);

	switch(action) {
		case DLG_DMQ_UPDATE:
			dlg->iflags |= DLG_IFLAG_DMQ_SYNC;
			dlg->dflags &= ~DLG_FLAG_CHANGED_PROF;
			srjson_AddNumberToObject(&jdoc, jdoc.root, "init_ts",
					dlg->init_ts);
			srjson_AddStrToObject(&jdoc, jdoc.root, "callid",
					dlg->callid.s, dlg->callid.len);

			srjson_AddStrToObject(&jdoc, jdoc.root, "from_uri",
					dlg->from_uri.s, dlg->from_uri.len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "to_uri",
					dlg->to_uri.s, dlg->to_uri.len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "req_uri",
					dlg->req_uri.s, dlg->req_uri.len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "tag1",
					dlg->tag[0].s, dlg->tag[0].len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1",
					dlg->cseq[0].s, dlg->cseq[0].len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1",
					dlg->route_set[0].s, dlg->route_set[0].len);
			srjson_AddStrToObject(&jdoc, jdoc.root, "contact1",
					dlg->contact[0].s, dlg->contact[0].len);

			if (dlg->vars != NULL) {
				srjson_t *pj = NULL;
				pj = srjson_CreateObject(&jdoc);
                for(var=dlg->vars ; var ; var=var->next) {
					srjson_AddStrToObject(&jdoc, pj, var->key.s,
							var->value.s, var->value.len);
                }
                srjson_AddItemToObject(&jdoc, jdoc.root, "vars", pj);
			}

			if (dlg->profile_links) {
				srjson_InitDoc(&prof_jdoc, NULL);
				dlg_profiles_to_json(dlg, &prof_jdoc);
				if(prof_jdoc.buf.s!=NULL) {
					LM_DBG("adding profiles: [%.*s]\n",
							prof_jdoc.buf.len, prof_jdoc.buf.s);
					srjson_AddStrToObject(&jdoc, jdoc.root, "profiles",
							prof_jdoc.buf.s, prof_jdoc.buf.len);
					prof_jdoc.free_fn(prof_jdoc.buf.s);
					prof_jdoc.buf.s = NULL;
				}
				srjson_DestroyDoc(&prof_jdoc);
			}
			/* intentional fallthrough */

		case DLG_DMQ_STATE:
			srjson_AddNumberToObject(&jdoc, jdoc.root, "state", dlg->state);
			switch (dlg->state) {
				case DLG_STATE_EARLY:
					srjson_AddNumberToObject(&jdoc, jdoc.root, "start_ts",
							dlg->start_ts);
					srjson_AddNumberToObject(&jdoc, jdoc.root, "lifetime",
							dlg->lifetime);

					srjson_AddStrToObject(&jdoc, jdoc.root, "tag1",
							dlg->tag[0].s, dlg->tag[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1",
							dlg->cseq[0].s, dlg->cseq[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1",
							dlg->route_set[0].s, dlg->route_set[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "contact1",
							dlg->contact[0].s, dlg->contact[0].len);
					break;
				case DLG_STATE_CONFIRMED:
					srjson_AddNumberToObject(&jdoc, jdoc.root, "start_ts",
							dlg->start_ts);
					srjson_AddNumberToObject(&jdoc, jdoc.root, "lifetime",
							dlg->lifetime);

					srjson_AddStrToObject(&jdoc, jdoc.root, "tag1",
							dlg->tag[0].s, dlg->tag[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "tag2",
							dlg->tag[1].s, dlg->tag[1].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "cseq1",
							dlg->cseq[0].s, dlg->cseq[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "cseq2",
							dlg->cseq[1].s, dlg->cseq[1].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "route_set1",
							dlg->route_set[0].s, dlg->route_set[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "route_set2",
							dlg->route_set[1].s, dlg->route_set[1].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "contact1",
							dlg->contact[0].s, dlg->contact[0].len);
					srjson_AddStrToObject(&jdoc, jdoc.root, "contact2",
							dlg->contact[1].s, dlg->contact[1].len);

					break;
				case DLG_STATE_DELETED:
					//dlg->iflags &= ~DLG_IFLAG_DMQ_SYNC;
					break;
				default:
					LM_DBG("not syncing state %u\n", dlg->state);
			}
			break;

		case DLG_DMQ_RM:
			srjson_AddNumberToObject(&jdoc, jdoc.root, "state", dlg->state);
			dlg->iflags &= ~DLG_IFLAG_DMQ_SYNC;
			break;

		case DLG_DMQ_NONE:
		case DLG_DMQ_SYNC:
			break;
	}
	if (needlock)
		dlg_unlock(d_table, &(d_table->entries[dlg->h_entry]));

	jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root);
	if(jdoc.buf.s==NULL) {
		LM_ERR("unable to serialize data\n");
		goto error;
	}
	jdoc.buf.len = strlen(jdoc.buf.s);
	LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s);
	if (dlg_dmq_send(&jdoc.buf, node)!=0) {
		goto error;
	}

	jdoc.free_fn(jdoc.buf.s);
	jdoc.buf.s = NULL;
	srjson_DestroyDoc(&jdoc);
	return 0;

error:
	if(jdoc.buf.s!=NULL) {
		jdoc.free_fn(jdoc.buf.s);
		jdoc.buf.s = NULL;
	}
	srjson_DestroyDoc(&jdoc);
	return -1;
}
예제 #8
0
/**
* @brief ht dmq callback
*/
int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* node)
{
	int content_length;
	str body;
	srjson_doc_t jdoc;
	srjson_t *it = NULL;
	static ucontact_info_t ci;

	int action, expires, cseq, flags, cflags, q, last_modified, methods, reg_id;
	str aor, ruid, c, received, path, callid, user_agent, instance;

	parse_from_header(msg);
	body = ((struct to_body*)msg->from->parsed)->uri;

	LM_DBG("dmq message received from %.*s\n", body.len, body.s);

	if(!msg->content_length) {
		LM_ERR("no content length header found\n");
		goto invalid;
	}
	content_length = get_content_length(msg);
	if(!content_length) {
		LM_DBG("content length is 0\n");
		goto invalid;
	}

	body.s = get_body(msg);
	body.len = content_length;

	if (!body.s) {
		LM_ERR("unable to get body\n");
		goto error;
	}

	srjson_InitDoc(&jdoc, NULL);
	jdoc.buf = body;
	if(jdoc.root == NULL) {
		jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
		if(jdoc.root == NULL)
		{
			LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
			goto invalid;
		}
	}

	for(it=jdoc.root->child; it; it = it->next)
	{
		if (it->string == NULL) continue;

		if (strcmp(it->string, "action")==0) {
			action = it->valueint;
		} else if (strcmp(it->string, "aor")==0) {
			aor.s = it->valuestring;
			aor.len = strlen(aor.s);
		} else if (strcmp(it->string, "ruid")==0) {
			ruid.s = it->valuestring;
			ruid.len = strlen(ruid.s);
		} else if (strcmp(it->string, "c")==0) {
			c.s = it->valuestring;
			c.len = strlen(c.s);
		} else if (strcmp(it->string, "received")==0) {
			received.s = it->valuestring;
			received.len = strlen(received.s);
		} else if (strcmp(it->string, "path")==0) {
			path.s = it->valuestring;
			path.len = strlen(path.s);
		} else if (strcmp(it->string, "callid")==0) {
			callid.s = it->valuestring;
			callid.len = strlen(callid.s);
		} else if (strcmp(it->string, "user_agent")==0) {
			user_agent.s = it->valuestring;
			user_agent.len = strlen(user_agent.s);
		} else if (strcmp(it->string, "instance")==0) {
			instance.s = it->valuestring;
			instance.len = strlen(instance.s);
		} else if (strcmp(it->string, "expires")==0) { //
			expires = it->valueint;
		} else if (strcmp(it->string, "cseq")==0) {
			cseq = it->valueint;
		} else if (strcmp(it->string, "flags")==0) {
			flags = it->valueint;
		} else if (strcmp(it->string, "cflags")==0) {
			cflags = it->valueint;
		} else if (strcmp(it->string, "q")==0) {
			q = it->valueint;
		} else if (strcmp(it->string, "last_modified")==0) {
			last_modified = it->valueint;
		} else if (strcmp(it->string, "methods")==0) {
			methods = it->valueint;
		} else if (strcmp(it->string, "reg_id")==0) {
			reg_id = it->valueint;
		} else {
			LM_ERR("unrecognized field in json object\n");
		}
	}
	memset( &ci, 0, sizeof(ucontact_info_t));
	ci.ruid = ruid;
	ci.c = &c;
	ci.received = received;
	ci.path = &path;
	ci.expires = expires;
	ci.q = q;
	ci.callid = &callid;
	ci.cseq = cseq;
	ci.flags = flags;
	ci.flags |= FL_RPL;
	ci.cflags = cflags;
	ci.user_agent = &user_agent;
	ci.methods = methods;
	ci.instance = instance;
	ci.reg_id = reg_id;
	ci.tcpconn_id = -1;
	ci.last_modified = last_modified;

	switch(action) {
		case DMQ_UPDATE:
			LM_DBG("Received DMQ_UPDATE. Update contact info...\n");
			add_contact(aor, &ci);
			break;
		case DMQ_RM:
			LM_DBG("Received DMQ_RM. Delete contact info...\n");
			delete_contact(aor, &ci);
			break;
		case DMQ_SYNC:
			LM_DBG("Received DMQ_SYNC. Sending all contacts...\n");
			usrloc_get_all_ucontact(node);
			break;
		case DMQ_NONE:
			LM_DBG("Received DMQ_NONE. Not used...\n");
			break;
		default:
			goto invalid;
	}

	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_200_rpl;
	resp->resp_code = 200;
	return 0;

invalid:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_400_rpl;
	resp->resp_code = 400;
	return 0;

error:
	srjson_DestroyDoc(&jdoc);
	resp->reason = dmq_500_rpl;
	resp->resp_code = 500;
	return 0;
}
예제 #9
0
int rtjson_update_branch(sip_msg_t *msg)
{
	sr_xavp_t *javp = NULL;
	sr_xavp_t *iavp = NULL;
	srjson_doc_t tdoc;
	srjson_t *tj = NULL;
	srjson_t *nj = NULL;
	str val;
	str xname;
	int i;

	xname.s = "json";
	xname.len = 4;
	javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname);
	if(javp==NULL || javp->val.v.s.len<=0) {
		LM_WARN("no json for routing\n");
		return -1;
	}

	xname.s = "idx";
	xname.len = 3;
	iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname);
	if(iavp==NULL) {
		LM_WARN("no idx for routing\n");
		return -1;
	}
	if(iavp->val.v.i<=0) {
		LM_WARN("invalid branch idx for routing\n");
		return -1;
	}

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing");
	if(nj==NULL || nj->valuestring==NULL) {
		LM_ERR("missing or invalid routing field\n");
		goto error;
	}
	val.s = nj->valuestring;
	val.len = strlen(val.s);

	if(val.len!=6 || strncmp(val.s, "serial", 6)!=0) {
		LM_DBG("not serial routing [%.*s]\n", val.len, val.s);
		goto error;
	}

	tj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
	if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
		LM_ERR("missing or invalid routes field\n");
		goto error;
	}
	nj = tj->child;

	i = 0;
	/* stop at number of branches - 1 */
	while(nj && i<iavp->val.v.i-1) {
		nj = nj->next;
		i++;
	}
	if(nj==NULL)
		goto error;

	if(rtjson_prepare_branch(msg, &tdoc, nj)<0)
		goto error;

	srjson_DestroyDoc(&tdoc);
	return 0;

error:
	srjson_DestroyDoc(&tdoc);
	return -1;

}
예제 #10
0
int rtjson_push_routes(sip_msg_t *msg)
{
	sr_xavp_t *javp = NULL;
	sr_xavp_t *iavp = NULL;
	srjson_doc_t tdoc;
	srjson_t *nj = NULL;
	str val;
	str xname;
	int ret;

	xname.s = "json";
	xname.len = 4;
	javp = xavp_get_child_with_sval(&_rtjson_xavp_name, &xname);
	if(javp==NULL || javp->val.v.s.len<=0) {
		LM_WARN("no json for routing\n");
		return -1;
	}

	xname.s = "idx";
	xname.len = 3;
	iavp = xavp_get_child_with_ival(&_rtjson_xavp_name, &xname);
	if(iavp==NULL) {
		LM_WARN("no idx for routing\n");
		return -1;
	}

	srjson_InitDoc(&tdoc, NULL);

	tdoc.root = srjson_Parse(&tdoc, javp->val.v.s.s);
	if(tdoc.root == NULL) {
		LM_ERR("invalid json doc [[%s]]\n", javp->val.v.s.s);
		srjson_DestroyDoc(&tdoc);
		return -1;
	}

	nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routing");
	if(nj==NULL || nj->valuestring==NULL) {
		LM_ERR("missing or invalid routing field\n");
		goto error;
	}
	val.s = nj->valuestring;
	val.len = strlen(val.s);

	if(val.len==6 && strncmp(val.s, "serial", 6)==0) {
		LM_DBG("supported routing [%.*s]\n", val.len, val.s);
		ret = rtjson_init_serial(msg, &tdoc, iavp);
	} else if(val.len==8 && strncmp(val.s, "parallel", 8)==0) {
		LM_DBG("supported routing [%.*s]\n", val.len, val.s);
		ret = rtjson_init_parallel(msg, &tdoc, iavp);
	} else {
		LM_ERR("unsupported routing [%.*s]\n", val.len, val.s);
		goto error;
	}

	srjson_DestroyDoc(&tdoc);
	return ret;

error:
	srjson_DestroyDoc(&tdoc);
	return -1;
}
예제 #11
0
/**
 * @brief ht dmq callback
 */
int ht_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t* dmq_node)
{
    int content_length;
    str body;
    ht_dmq_action_t action = HT_DMQ_NONE;
    str htname, cname;
    int type = 0, mode = 0;
    int_str val;
    srjson_doc_t jdoc;
    srjson_t *it = NULL;

    /* received dmq message */
    LM_DBG("dmq message received\n");

    if(!msg->content_length) {
        LM_ERR("no content length header found\n");
        goto invalid;
    }
    content_length = get_content_length(msg);
    if(!content_length) {
        LM_DBG("content length is 0\n");
        goto invalid;
    }

    body.s = get_body(msg);
    body.len = content_length;

    if (!body.s) {
        LM_ERR("unable to get body\n");
        goto error;
    }

    /* parse body */
    LM_DBG("body: %.*s\n", body.len, body.s);

    srjson_InitDoc(&jdoc, NULL);
    jdoc.buf = body;

    if(jdoc.root == NULL) {
        jdoc.root = srjson_Parse(&jdoc, jdoc.buf.s);
        if(jdoc.root == NULL)
        {
            LM_ERR("invalid json doc [[%s]]\n", jdoc.buf.s);
            goto invalid;
        }
    }

    for(it=jdoc.root->child; it; it = it->next)
    {
        LM_DBG("found field: %s\n", it->string);
        if (strcmp(it->string, "action")==0) {
            action = it->valueint;
        } else if (strcmp(it->string, "htname")==0) {
            htname.s = it->valuestring;
            htname.len = strlen(htname.s);
        } else if (strcmp(it->string, "cname")==0) {
            cname.s = it->valuestring;
            cname.len = strlen(cname.s);
        } else if (strcmp(it->string, "type")==0) {
            type = it->valueint;
        } else if (strcmp(it->string, "strval")==0) {
            val.s.s = it->valuestring;
            val.s.len = strlen(val.s.s);
        } else if (strcmp(it->string, "intval")==0) {
            val.n = it->valueint;
        } else if (strcmp(it->string, "mode")==0) {
            mode = it->valueint;
        } else {
            LM_ERR("unrecognized field in json object\n");
            goto invalid;
        }
    }

    if (ht_dmq_replay_action(action, &htname, &cname, type, &val, mode)!=0) {
        LM_ERR("failed to replay action\n");
        goto error;
    }

    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_200_rpl;
    resp->resp_code = 200;
    return 0;

invalid:
    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_400_rpl;
    resp->resp_code = 400;
    return 0;

error:
    srjson_DestroyDoc(&jdoc);
    resp->reason = dmq_500_rpl;
    resp->resp_code = 500;
    return 0;
}
예제 #12
0
int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level)
{
	int i;
	pv_value_t value;
	pv_cache_t **_pv_cache = pv_cache_get_table();
	pv_cache_t *el = NULL;
	srjson_doc_t jdoc;
	srjson_t *jobj = NULL;
	char *output = NULL;
	str item_name = STR_NULL;
	static char iname[128];
	int result = -1;

	if(_pv_cache==NULL)
	{
		LM_ERR("cannot access pv_cache\n");
		return -1;
	}

	memset(_dbg_xavp_dump, 0, sizeof(str*)*DBG_XAVP_DUMP_SIZE);
	srjson_InitDoc(&jdoc, NULL);
	if(jdoc.root==NULL)
	{
		jdoc.root = srjson_CreateObject(&jdoc);
		if(jdoc.root==NULL)
		{
			LM_ERR("cannot create json root\n");
			goto error;
		}
	}
	for(i=0;i<PV_CACHE_SIZE;i++)
	{
		el = _pv_cache[i];
		while(el)
		{
			if(!(el->spec.type==PVT_AVP||
				el->spec.type==PVT_SCRIPTVAR||
				el->spec.type==PVT_XAVP||
				el->spec.type==PVT_OTHER)||
				!((el->spec.type==PVT_AVP&&mask&DBG_DP_AVP)||
				(el->spec.type==PVT_XAVP&&mask&DBG_DP_XAVP)||
				(el->spec.type==PVT_SCRIPTVAR&&mask&DBG_DP_SCRIPTVAR)||
				(el->spec.type==PVT_OTHER&&mask&DBG_DP_OTHER))||
				(el->spec.trans!=NULL))
			{
				el = el->next;
				continue;
			}
			jobj = NULL;
			item_name.len = 0;
			item_name.s = 0;
			iname[0] = '\0';
			if(el->spec.type==PVT_AVP)
			{
				if(el->spec.pvp.pvi.type==PV_IDX_ALL||
					(el->spec.pvp.pvi.type==PV_IDX_INT&&el->spec.pvp.pvi.u.ival!=0))
				{
					el = el->next;
					continue;
				}
				else
				{
					if(_dbg_get_array_avp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
					{
						LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
						el = el->next;
						continue;
					}
					if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
					{
						el = el->next;
						continue;
					}
					snprintf(iname, 128, "$avp(%.*s)", item_name.len, item_name.s);
				}
			}
			else if(el->spec.type==PVT_XAVP)
			{
				if(_dbg_xavp_dump_lookup(&el->spec.pvp)!=0)
				{
					el = el->next;
					continue;
				}
				if(_dbg_get_obj_xavp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
				{
					LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
					el = el->next;
					continue;
				}
				if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
				{
					el = el->next;
					continue;
				}
				snprintf(iname, 128, "$xavp(%.*s)", item_name.len, item_name.s);
			}
			else
			{
				if(pv_get_spec_value(msg, &el->spec, &value)!=0)
				{
					LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
					el = el->next;
					continue;
				}
				if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE))
				{
					if(mask&DBG_DP_NULL)
					{
						jobj = srjson_CreateNull(&jdoc);
					}
					else
					{
						el = el->next;
						continue;
					}
				}else if(value.flags&(PV_VAL_INT)){
					jobj = srjson_CreateNumber(&jdoc, value.ri);
				}else if(value.flags&(PV_VAL_STR)){
					jobj = srjson_CreateStr(&jdoc, value.rs.s, value.rs.len);
				}else {
					LM_WARN("el->pvname[%.*s] value[%d] unhandled\n", el->pvname.len, el->pvname.s,
						value.flags);
					el = el->next;
					continue;
				}
				if(jobj==NULL)
				{
					LM_ERR("el->pvname[%.*s] empty json object\n", el->pvname.len,
						el->pvname.s);
					goto error;
				}
				snprintf(iname, 128, "%.*s", el->pvname.len, el->pvname.s);
			}
			if(jobj!=NULL)
			{
				srjson_AddItemToObject(&jdoc, jdoc.root, iname, jobj);
			}
			el = el->next;
		}
	}
	output = srjson_PrintUnformatted(&jdoc, jdoc.root);
	if(output==NULL)
	{
		LM_ERR("cannot print json doc\n");
		goto error;
	}
	LOG(level, "%s\n", output);
	result = 0;

error:
	if(output!=NULL) jdoc.free_fn(output);
	srjson_DestroyDoc(&jdoc);

	return result;
}