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.
kamailio/modules/tsilo/ts_rpc.c

223 lines
5.0 KiB

/**
* Copyright (C) 2014 Federico Cabiddu (federico.cabiddu@gmail.com)
*
* This file is part of Kamailio, a free SIP server.
*
* Kamailio 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
*
* Kamailio 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include <stdio.h>
#include "ts_hash.h"
#include "ts_rpc.h"
static const char* rpc_tsilo_dump_doc[2] = {
"Dump tsilo transactions table",
0
};
static const char* rpc_tsilo_lookup_doc[2] = {
"Lookup one R-URI in the tsilo transactions table",
0
};
/************************ helper functions ****************************/
/*!
* \brief Add a node for a transaction
*/
static inline int rpc_dump_transaction(rpc_t* rpc, void* ctx, void *ih, ts_transaction_t* t)
{
void* vh;
if(t==NULL)
return -1;
if(rpc->struct_add(ih, "{", "Transaction", &vh)<0)
{
rpc->fault(ctx, 500, "Internal error creating transaction struct");
return -1;
}
if(rpc->struct_add(vh, "d", "Tindex", t->tindex)<0) {
rpc->fault(ctx, 500, "Internal error adding tindex");
return -1;
}
if(rpc->struct_add(vh, "d", "Tlabel", t->tlabel)<0) {
rpc->fault(ctx, 500, "Internal error adding tlabel");
return -1;
}
return 0;
}
/*************************** RPC functions *****************************/
/*!
* \brief Dump the content of the tsilo table
* \param rpc RPC node that should be filled
* \param c RPC void pointer
*/
static void rpc_tsilo_dump(rpc_t *rpc, void *c)
{
ts_transaction_t* trans = NULL;
struct ts_urecord* record = NULL;
struct ts_entry* entry = NULL;
str brief = {0, 0};
int max, res, n, ntrans, i;
int short_dump = 0;
void* th;
void* ah;
void* ih;
void* sh;
rpc->scan(c, "*S", &brief);
if(brief.len==5 && (strncmp(brief.s, "brief", 5)==0))
/* short version */
short_dump = 1;
if (rpc->add(c, "{", &th) < 0)
{
rpc->fault(c, 500, "Internal error creating top rpc");
return;
}
if (short_dump==0) {
res = rpc->struct_add(th, "d{",
"Size", t_table->size,
"R-URIs", &ah);
} else {
res = rpc->struct_add(th, "d",
"Size", t_table->size);
}
if (res<0)
{
rpc->fault(c, 500, "Internal error creating inner struct");
return;
}
/* add the entries per hash */
for(i=0,n=0,max=0,ntrans=0; i<t_table->size; i++) {
lock_entry(&t_table->entries[i]);
entry = &t_table->entries[i];
n += entry->n;
if(max<entry->n)
max= entry->n;
for( record = entry->first ; record ; record=record->next ) {
/* add entry */
if(short_dump==0)
{
if(rpc->struct_add(ah, "Sd{",
"R-URI", &record->ruri,
"Hash", record->rurihash,
"Transactions", &ih)<0)
{
unlock_entry(&t_table->entries[i]);
rpc->fault(c, 500, "Internal error creating ruri struct");
return;
}
}
for( trans=record->transactions ; trans ; trans=trans->next) {
ntrans += 1;
if (short_dump==0) {
if (rpc_dump_transaction(rpc, c, ih, trans) == -1) {
unlock_entry(&t_table->entries[i]);
return;
}
}
}
}
unlock_entry(&t_table->entries[i]);
}
/* extra attributes node */
if(rpc->struct_add(th, "{", "Stats", &sh)<0) {
rpc->fault(c, 500, "Internal error creating stats struct");
return;
}
if(rpc->struct_add(sh, "ddd",
"RURIs", n,
"Max-Slots", max,
"Transactions", ntrans)<0)
{
rpc->fault(c, 500, "Internal error adding stats");
return;
}
}
/*!
* \brief Show the transactions for a given R-URI
* \param rpc RPC node that should be filled
* \param c RPC void pointer
*/
static void rpc_tsilo_lookup(rpc_t *rpc, void *c)
{
ts_transaction_t* trans;
struct ts_urecord* record;
str ruri = {0, 0};
int res;
void* th;
if (rpc->scan(c, "S", &ruri) != 1) {
rpc->fault(c, 500, "No RURI to lookup specified");
return;
}
lock_entry_by_ruri(&ruri);
/* look for urecord */
res = get_ts_urecord(&ruri, &record);
if (res) {
unlock_entry_by_ruri(&ruri);
rpc->fault(c, 404, "RURI not found in tsilo table");
return;
}
if (rpc->add(c, "{", &th) < 0)
{
unlock_entry_by_ruri(&ruri);
rpc->fault(c, 500, "Internal error creating top rpc");
return;
}
/* add the transactions */
for( trans=record->transactions ; trans ; trans=trans->next) {
if (rpc_dump_transaction(rpc, c, th, trans) == -1) {
unlock_entry_by_ruri(&ruri);
return;
}
}
unlock_entry_by_ruri(&ruri);
return;
}
rpc_export_t rpc_methods[] = {
{ "ts.dump", rpc_tsilo_dump, rpc_tsilo_dump_doc, 0 },
{ "ts.lookup", rpc_tsilo_lookup, rpc_tsilo_lookup_doc, 0 },
{ 0, 0, 0, 0}
};