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.
1640 lines
38 KiB
1640 lines
38 KiB
/*
|
|
* $Id$
|
|
*
|
|
* pua db - presence user agent database support
|
|
*
|
|
* Copyright (C) 2011 Crocodile RCS Ltd
|
|
*
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "../../mem/mem.h"
|
|
#include "../../mem/shm_mem.h"
|
|
#include "../../dprint.h"
|
|
#include "../../lib/srdb1/db.h"
|
|
#include "../../parser/msg_parser.h"
|
|
#include "../../parser/parse_from.h"
|
|
|
|
#include "pua.h"
|
|
#include "pua_db.h"
|
|
|
|
/* database colums */
|
|
static str str_id_col = str_init( "id" );
|
|
static str str_pres_uri_col = str_init("pres_uri");
|
|
static str str_pres_id_col = str_init("pres_id");
|
|
static str str_expires_col= str_init("expires");
|
|
static str str_flag_col= str_init("flag");
|
|
static str str_etag_col= str_init("etag");
|
|
static str str_tuple_id_col= str_init("tuple_id");
|
|
static str str_watcher_uri_col= str_init("watcher_uri");
|
|
static str str_call_id_col= str_init("call_id");
|
|
static str str_to_tag_col= str_init("to_tag");
|
|
static str str_from_tag_col= str_init("from_tag");
|
|
static str str_cseq_col= str_init("cseq");
|
|
static str str_event_col= str_init("event");
|
|
static str str_record_route_col= str_init("record_route");
|
|
static str str_contact_col= str_init("contact");
|
|
static str str_remote_contact_col= str_init("remote_contact");
|
|
static str str_extra_headers_col= str_init("extra_headers");
|
|
static str str_desired_expires_col= str_init("desired_expires");
|
|
static str str_version_col = str_init("version");
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
void free_results_puadb( db1_res_t *res )
|
|
|
|
{
|
|
if (res)
|
|
{
|
|
pua_dbf.free_result(pua_db, res);
|
|
res = NULL;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
static void extract_row( db_val_t *values, ua_pres_t *result )
|
|
|
|
{
|
|
|
|
if (result->pres_uri != NULL )
|
|
{
|
|
result->pres_uri->s = (char *)VAL_STRING(values+1);
|
|
result->pres_uri->len = strlen(VAL_STRING(values+1));
|
|
}
|
|
|
|
result->id.s = (char *)VAL_STRING(values+2);
|
|
result->id.len = strlen(VAL_STRING(values+2));
|
|
|
|
result->event = VAL_INT(values+3);
|
|
|
|
result->expires = VAL_INT(values+4);
|
|
|
|
result->desired_expires = VAL_INT(values+5);
|
|
|
|
result->flag = VAL_INT(values+6);
|
|
|
|
/* publish */
|
|
result->etag.s = (char *)VAL_STRING(values+7);
|
|
result->etag.len = strlen(VAL_STRING(values+7));
|
|
|
|
result->tuple_id.s = (char *)VAL_STRING(values+8);
|
|
result->tuple_id.len = strlen(VAL_STRING(values+8));
|
|
|
|
/* subscribe */
|
|
if (result->watcher_uri != NULL )
|
|
{
|
|
result->watcher_uri->s = (char *)VAL_STRING(values+9);
|
|
result->watcher_uri->len = strlen(VAL_STRING(values+9));
|
|
}
|
|
|
|
result->call_id.s = (char *)VAL_STRING(values+10);
|
|
result->call_id.len = strlen(VAL_STRING(values+10));
|
|
|
|
result->to_tag.s = (char *)VAL_STRING(values+11);
|
|
result->to_tag.len = strlen(VAL_STRING(values+11));
|
|
|
|
result->from_tag.s = (char *)VAL_STRING(values+12);
|
|
result->from_tag.len = strlen(VAL_STRING(values+12));
|
|
|
|
result->cseq = VAL_INT(values+13);
|
|
|
|
result->record_route.s = (char *)VAL_STRING(values+14);
|
|
result->record_route.len = strlen(VAL_STRING(values+14));
|
|
|
|
result->contact.s = (char *)VAL_STRING(values+15);
|
|
result->contact.len = strlen(VAL_STRING(values+15));
|
|
|
|
result->remote_contact.s = (char *)VAL_STRING(values+16);
|
|
result->remote_contact.len = strlen(VAL_STRING(values+16));
|
|
|
|
result->version = VAL_INT(values+17);
|
|
|
|
if (result->extra_headers != NULL )
|
|
{
|
|
result->extra_headers->s = (char *)VAL_STRING(values+18);
|
|
result->extra_headers->len = strlen(VAL_STRING(values+18));
|
|
}
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int clean_puadb( int update_period, int min_expires )
|
|
|
|
{
|
|
int i, nr_rows;
|
|
db_row_t *rows;
|
|
db_val_t *values;
|
|
db_key_t q_cols[1];
|
|
db1_res_t *res= NULL;
|
|
db_val_t q_vals[1];
|
|
db_op_t q_ops[1];
|
|
int id;
|
|
time_t now;
|
|
ua_pres_t p;
|
|
str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
|
|
|
|
memset(&p, 0, sizeof(p));
|
|
p.pres_uri = &pres_uri;
|
|
p.watcher_uri = &watcher_uri;
|
|
p.extra_headers = &extra_headers;
|
|
|
|
now = time(NULL);
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[0] = &str_expires_col;
|
|
q_vals[0].type = DB1_INT;
|
|
q_vals[0].nul = 0;
|
|
q_vals[0].val.int_val = now+update_period;
|
|
q_ops[0] = OP_LT;
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0) {
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, q_cols, q_ops,
|
|
q_vals, NULL, 1, 0, 0, &res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (RES_ROW_N(res) == 0)
|
|
{
|
|
/* no match */
|
|
LM_INFO( "No records matched for clean\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(0);
|
|
}
|
|
|
|
do {
|
|
nr_rows = RES_ROW_N(res);
|
|
|
|
/* get the results and update matching entries */
|
|
rows = RES_ROWS(res);
|
|
|
|
for (i=0; i < nr_rows; i++)
|
|
{
|
|
values = ROW_VALUES(rows+i);
|
|
|
|
extract_row( values, &p );
|
|
id = VAL_INT(values);
|
|
|
|
if((p.desired_expires> p.expires + min_expires) || (p.desired_expires== 0 ))
|
|
{
|
|
if(update_pua(&p)< 0)
|
|
{
|
|
LM_ERR("update_pua failed\n");
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if(p.expires < now - 10)
|
|
{
|
|
LM_DBG("Found expired: uri= %.*s\n", p.pres_uri->len, p.pres_uri->s);
|
|
q_cols[0] = &str_id_col;
|
|
q_vals[0].type = DB1_INT;
|
|
q_vals[0].nul = 0;
|
|
q_vals[0].val.int_val = id;
|
|
|
|
if ( pua_dbf.delete(pua_db, q_cols, 0, q_vals, 1) < 0 )
|
|
{
|
|
LM_ERR( "Failed to delete from db\n" );
|
|
}
|
|
}
|
|
|
|
}
|
|
} while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
|
|
&& (RES_ROWS(res)>0));
|
|
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(0);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int is_dialog_puadb(ua_pres_t *pres)
|
|
|
|
{
|
|
int nr_rows;
|
|
db_key_t q_cols[3], res_cols[1];
|
|
db1_res_t *res= NULL;
|
|
db_val_t q_vals[3];
|
|
int n_query_cols= 0, n_res_cols=0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
/* return the id column, even though don't actually need */
|
|
res_cols[n_res_cols] = &str_id_col;
|
|
n_res_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
|
|
res_cols,n_query_cols,n_res_cols,0,&res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(-1);
|
|
}
|
|
|
|
nr_rows = RES_ROW_N(res);
|
|
pua_dbf.free_result(pua_db, res);
|
|
|
|
if (nr_rows == 0)
|
|
{
|
|
/* no match */
|
|
LM_DBG("No rows found.\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (nr_rows != 1)
|
|
{
|
|
LM_WARN("Too many rows found (%d)\n", nr_rows);
|
|
/* no need to return here - drop thro */
|
|
}
|
|
|
|
/* established dialog */
|
|
if(pres->to_tag.len>0)
|
|
return 0;
|
|
/* temporary dialog */
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int get_record_id_puadb(ua_pres_t *pres, str **rec_id )
|
|
|
|
{
|
|
int nr_rows;
|
|
db_row_t *rows;
|
|
db_key_t q_cols[3], res_cols[2];
|
|
db1_res_t *res= NULL;
|
|
db_val_t q_vals[3];
|
|
int n_query_cols=0, n_res_cols=0;
|
|
db_val_t *values;
|
|
str *id;
|
|
str to_tag;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
res_cols[n_res_cols] = &str_pres_id_col;
|
|
n_res_cols++;
|
|
|
|
*rec_id = NULL;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
|
|
res_cols,n_query_cols,n_res_cols,0,&res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(-1);
|
|
}
|
|
|
|
nr_rows = RES_ROW_N(res);
|
|
|
|
switch (nr_rows)
|
|
{
|
|
case 1:
|
|
rows = RES_ROWS(res);
|
|
values = ROW_VALUES(rows);
|
|
break;
|
|
|
|
case 0:
|
|
/* no match */
|
|
LM_DBG("No rows found. Looking for temporary dialog\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
|
|
n_query_cols--;
|
|
|
|
res_cols[n_res_cols] = &str_to_tag_col;
|
|
n_res_cols++;
|
|
|
|
if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
|
|
res_cols,n_query_cols,n_res_cols,0,&res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(-1);
|
|
}
|
|
|
|
nr_rows = RES_ROW_N(res);
|
|
|
|
if (nr_rows == 1)
|
|
{
|
|
rows = RES_ROWS(res);
|
|
values = ROW_VALUES(rows);
|
|
|
|
to_tag.s = (char *) VAL_STRING(values + 1);
|
|
to_tag.len = strlen(to_tag.s);
|
|
|
|
if (to_tag.len == 0 ||
|
|
(to_tag.len > 0
|
|
&& strncmp(to_tag.s, pres->to_tag.s, pres->to_tag.len) == 0))
|
|
{
|
|
LM_DBG( "Found a (possibly temporary) Dialog\n" );
|
|
break;
|
|
}
|
|
else
|
|
LM_WARN("Failed to find temporary dialog for To-tag: %.*s, found To-tag: %.*s\n",
|
|
pres->to_tag.len, pres->to_tag.s, to_tag.len, to_tag.s);
|
|
}
|
|
|
|
if (nr_rows <= 1)
|
|
{
|
|
LM_DBG("Dialog not found\n" );
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(0);
|
|
}
|
|
|
|
/* Fall-thru */
|
|
|
|
default:
|
|
LM_ERR("Too many rows found (%d)\n", nr_rows);
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(-1);
|
|
}
|
|
|
|
id= (str*)pkg_malloc(sizeof(str));
|
|
|
|
if(id== NULL)
|
|
{
|
|
LM_ERR("No more memory\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(-1);
|
|
}
|
|
|
|
id->s= (char*)pkg_malloc( strlen(VAL_STRING(values)) * sizeof(char));
|
|
|
|
if(id->s== NULL)
|
|
{
|
|
LM_ERR("No more memory\n");
|
|
pkg_free(id);
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(-1);
|
|
}
|
|
|
|
memcpy(id->s, VAL_STRING(values), strlen(VAL_STRING(values)) );
|
|
id->len= strlen(VAL_STRING(values));
|
|
|
|
*rec_id= id;
|
|
pua_dbf.free_result(pua_db, res);
|
|
|
|
LM_DBG("Found id=%.*s\n", id->len, id->s);
|
|
return(0);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
int convert_temporary_dialog_puadb(ua_pres_t *pres)
|
|
{
|
|
db_key_t query_cols[18];
|
|
db_val_t query_vals[18];
|
|
int n_query_cols = 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
/* The columns I need to query to find the temporary dialog */
|
|
query_cols[n_query_cols] = &str_pres_id_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->id;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_pres_uri_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val.s = pres->pres_uri->s;
|
|
query_vals[n_query_cols].val.str_val.len = pres->pres_uri->len;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_call_id_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_from_tag_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
/* The columns I need to fill in to convert a temporary dialog to a dialog */
|
|
query_cols[n_query_cols] = &str_expires_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->expires;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_desired_expires_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->desired_expires;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_flag_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->flag;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_to_tag_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_cseq_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->cseq;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_record_route_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->record_route;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_contact_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->contact;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_remote_contact_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val = pres->remote_contact;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_version_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->version;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_extra_headers_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
if (pres->extra_headers)
|
|
{
|
|
query_vals[n_query_cols].val.str_val.s = pres->extra_headers->s;
|
|
query_vals[n_query_cols].val.str_val.len = pres->extra_headers->len;
|
|
}
|
|
else
|
|
{
|
|
query_vals[n_query_cols].val.str_val.s = "";
|
|
query_vals[n_query_cols].val.str_val.len = 0;
|
|
}
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_event_col;
|
|
query_vals[n_query_cols].type = DB1_INT;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.int_val = pres->event;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_watcher_uri_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val.s = pres->watcher_uri->s;
|
|
query_vals[n_query_cols].val.str_val.len = pres->watcher_uri->len;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_etag_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val.s = 0;
|
|
query_vals[n_query_cols].val.str_val.len = 0;
|
|
n_query_cols++;
|
|
|
|
query_cols[n_query_cols] = &str_tuple_id_col;
|
|
query_vals[n_query_cols].type = DB1_STR;
|
|
query_vals[n_query_cols].nul = 0;
|
|
query_vals[n_query_cols].val.str_val.s = 0;
|
|
query_vals[n_query_cols].val.str_val.len = 0;
|
|
n_query_cols++;
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.replace != NULL)
|
|
{
|
|
if (pua_dbf.replace(pua_db, query_cols, query_vals, n_query_cols,
|
|
4, 0) < 0)
|
|
{
|
|
LM_ERR("Failed replace db\n");
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pua_dbf.update(pua_db, query_cols, 0, query_vals,
|
|
query_cols + 4, query_vals + 4, 4, n_query_cols - 4) < 0)
|
|
{
|
|
LM_ERR("Failed update db\n");
|
|
return -1;
|
|
}
|
|
|
|
LM_DBG("affected_rows: %d\n", pua_dbf.affected_rows(pua_db));
|
|
if (pua_dbf.affected_rows(pua_db) == 0)
|
|
{
|
|
if (pua_dbf.insert(pua_db, query_cols, query_vals, n_query_cols) < 0)
|
|
{
|
|
LM_ERR("Failed insert db\n");
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
shm_free(pres->remote_contact.s);
|
|
shm_free(pres);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int insert_record_puadb(ua_pres_t* pres)
|
|
|
|
{
|
|
db_key_t db_cols[18];
|
|
db_val_t db_vals[18];
|
|
int n_cols= 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
db_cols[n_cols] = &str_pres_uri_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->pres_uri->s;
|
|
db_vals[n_cols].val.str_val.len = pres->pres_uri->len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_pres_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->id.s;
|
|
db_vals[n_cols].val.str_val.len = pres->id.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_event_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->event;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_expires_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->expires;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_desired_expires_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->desired_expires;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_flag_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->flag;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_etag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->etag.s;
|
|
db_vals[n_cols].val.str_val.len = pres->etag.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_tuple_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->tuple_id.s;
|
|
db_vals[n_cols].val.str_val.len = pres->tuple_id.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_watcher_uri_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_call_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_to_tag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_from_tag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_cseq_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_record_route_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_contact_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_remote_contact_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_version_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->version;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_extra_headers_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
if (pres->extra_headers)
|
|
{
|
|
db_vals[n_cols].val.str_val.s = pres->extra_headers->s;
|
|
db_vals[n_cols].val.str_val.len = pres->extra_headers->len;
|
|
}
|
|
else
|
|
{
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
}
|
|
n_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.insert(pua_db, db_cols, db_vals, n_cols) < 0)
|
|
{
|
|
LM_ERR("DB insert failed\n");
|
|
return(-1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
ua_pres_t *get_record_puadb(str pres_id, str *etag, ua_pres_t *result, db1_res_t **dbres)
|
|
{
|
|
db_key_t q_cols[2];
|
|
db_val_t q_vals[2], *values;
|
|
db_row_t *rows;
|
|
db1_res_t *res;
|
|
int n_query_cols = 0, nr_rows;
|
|
db_query_f query_fn = pua_dbf.query_lock ? pua_dbf.query_lock : pua_dbf.query;
|
|
|
|
q_cols[n_query_cols] = &str_pres_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres_id;
|
|
n_query_cols++;
|
|
|
|
if (etag != NULL)
|
|
{
|
|
q_cols[n_query_cols] = &str_etag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val.s = etag->s;
|
|
q_vals[n_query_cols].val.str_val.len = etag->len;
|
|
n_query_cols++;
|
|
}
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if(query_fn(pua_db, q_cols, 0, q_vals,
|
|
NULL,n_query_cols,0,0,&res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(NULL);
|
|
}
|
|
|
|
nr_rows = RES_ROW_N(res);
|
|
|
|
if (nr_rows == 0)
|
|
{
|
|
/* no match */
|
|
LM_DBG("No rows found\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(NULL);
|
|
}
|
|
|
|
if (nr_rows != 1)
|
|
{
|
|
LM_ERR("Too many rows found (%d)\n", nr_rows);
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(NULL);
|
|
}
|
|
|
|
/* get the results and fill in return data structure */
|
|
rows = RES_ROWS(res);
|
|
values = ROW_VALUES(rows);
|
|
|
|
extract_row( values, result );
|
|
|
|
*dbres = res;
|
|
|
|
return(result);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int delete_record_puadb(ua_pres_t *pres)
|
|
{
|
|
db_key_t q_cols[2];
|
|
db_val_t q_vals[2];
|
|
int n_query_cols = 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
q_cols[n_query_cols] = &str_pres_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->id;
|
|
n_query_cols++;
|
|
|
|
if (pres->etag.s)
|
|
{
|
|
q_cols[n_query_cols] = &str_etag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->etag;
|
|
n_query_cols++;
|
|
}
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
|
|
{
|
|
LM_ERR("deleting record\n");
|
|
return -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int update_record_puadb(ua_pres_t *pres, int expires, str *etag)
|
|
{
|
|
db_key_t q_cols[2], u_cols[3];
|
|
db_val_t q_vals[2], u_vals[3];
|
|
int n_query_cols = 0, n_update_cols = 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
q_cols[n_query_cols] = &str_pres_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->id;
|
|
n_query_cols++;
|
|
|
|
if (pres->etag.s)
|
|
{
|
|
q_cols[n_query_cols] = &str_etag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->etag;
|
|
n_query_cols++;
|
|
}
|
|
|
|
u_cols[n_update_cols] = &str_desired_expires_col;
|
|
u_vals[n_update_cols].type = DB1_INT;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.int_val = pres->desired_expires;
|
|
n_update_cols++;
|
|
|
|
u_cols[n_update_cols] = &str_expires_col;
|
|
u_vals[n_update_cols].type = DB1_INT;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.int_val = expires + (int) time(NULL);
|
|
n_update_cols++;
|
|
|
|
if (etag)
|
|
{
|
|
u_cols[n_update_cols] = &str_etag_col;
|
|
u_vals[n_update_cols].type = DB1_STR;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.str_val.s = etag->s;
|
|
u_vals[n_update_cols].val.str_val.len = etag->len;
|
|
n_update_cols++;
|
|
}
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
|
|
n_query_cols, n_update_cols) < 0)
|
|
{
|
|
LM_ERR("updating dialog\n");
|
|
return -1;
|
|
}
|
|
|
|
if (pua_dbf.affected_rows != NULL)
|
|
return pua_dbf.affected_rows(pua_db);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int insert_dialog_puadb(ua_pres_t* pres)
|
|
|
|
{
|
|
db_key_t db_cols[18];
|
|
db_val_t db_vals[18];
|
|
int n_cols= 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
db_cols[n_cols] = &str_pres_uri_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->pres_uri->s;
|
|
db_vals[n_cols].val.str_val.len = pres->pres_uri->len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_pres_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->id.s;
|
|
db_vals[n_cols].val.str_val.len = pres->id.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_event_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->event;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_expires_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->expires;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_desired_expires_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->desired_expires;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_flag_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->flag;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_etag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_tuple_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_watcher_uri_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->watcher_uri->s;
|
|
db_vals[n_cols].val.str_val.len = pres->watcher_uri->len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_call_id_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->call_id.s;
|
|
db_vals[n_cols].val.str_val.len = pres->call_id.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_to_tag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->to_tag.s;
|
|
db_vals[n_cols].val.str_val.len = pres->to_tag.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_from_tag_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->from_tag.s;
|
|
db_vals[n_cols].val.str_val.len = pres->from_tag.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_cseq_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->cseq;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_record_route_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->record_route.s;
|
|
db_vals[n_cols].val.str_val.len = pres->record_route.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_contact_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->contact.s;
|
|
db_vals[n_cols].val.str_val.len = pres->contact.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_remote_contact_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.str_val.s = pres->remote_contact.s;
|
|
db_vals[n_cols].val.str_val.len = pres->remote_contact.len;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_version_col;
|
|
db_vals[n_cols].type = DB1_INT;
|
|
db_vals[n_cols].nul = 0;
|
|
db_vals[n_cols].val.int_val = pres->version;
|
|
n_cols++;
|
|
|
|
db_cols[n_cols] = &str_extra_headers_col;
|
|
db_vals[n_cols].type = DB1_STR;
|
|
db_vals[n_cols].nul = 0;
|
|
if (pres->extra_headers)
|
|
{
|
|
db_vals[n_cols].val.str_val.s = pres->extra_headers->s;
|
|
db_vals[n_cols].val.str_val.len = pres->extra_headers->len;
|
|
}
|
|
else
|
|
{
|
|
db_vals[n_cols].val.str_val.s = "";
|
|
db_vals[n_cols].val.str_val.len = 0;
|
|
}
|
|
n_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.insert(pua_db, db_cols, db_vals, n_cols) < 0)
|
|
{
|
|
LM_ERR("DB insert failed\n");
|
|
return(-1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
ua_pres_t *get_dialog_puadb(str pres_id, str *pres_uri, ua_pres_t *result, db1_res_t **dbres)
|
|
{
|
|
db_key_t q_cols[2];
|
|
db_val_t q_vals[2], *values;
|
|
db_row_t *rows;
|
|
db1_res_t *res;
|
|
int n_query_cols = 0, nr_rows;
|
|
db_query_f query_fn = pua_dbf.query_lock ? pua_dbf.query_lock : pua_dbf.query;
|
|
|
|
if (pres_uri == NULL)
|
|
{
|
|
LM_ERR("Attempting to search for a dialog without specifying pres_uri\n");
|
|
return(NULL);
|
|
}
|
|
|
|
q_cols[n_query_cols] = &str_pres_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_pres_uri_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val.s = pres_uri->s;
|
|
q_vals[n_query_cols].val.str_val.len = pres_uri->len;
|
|
n_query_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if(query_fn(pua_db, q_cols, 0, q_vals,
|
|
NULL,n_query_cols,0,0,&res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return(NULL);
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return(NULL);
|
|
}
|
|
|
|
nr_rows = RES_ROW_N(res);
|
|
|
|
if (nr_rows == 0)
|
|
{
|
|
/* no match */
|
|
LM_DBG("No rows found\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return(NULL);
|
|
}
|
|
else if (nr_rows > 1)
|
|
{
|
|
LM_ERR("Too many rows found (%d)... deleting\n", nr_rows);
|
|
pua_dbf.free_result(pua_db, res);
|
|
|
|
if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
|
|
LM_ERR("deleting record(s)\n");
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
/* get the results and fill in return data structure */
|
|
rows = RES_ROWS(res);
|
|
values = ROW_VALUES(rows);
|
|
|
|
extract_row( values, result );
|
|
|
|
/*pua_dbf.free_result(pua_db, res);*/
|
|
*dbres = res;
|
|
|
|
return(result);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int delete_dialog_puadb(ua_pres_t *pres)
|
|
{
|
|
db_key_t q_cols[3];
|
|
db_val_t q_vals[3];
|
|
int n_query_cols = 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
if (pres->to_tag.len > 0 && pres->to_tag.s != NULL)
|
|
{
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
}
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.delete(pua_db, q_cols, 0, q_vals, n_query_cols) < 0)
|
|
{
|
|
LM_ERR("deleting record\n");
|
|
return -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int update_dialog_puadb(ua_pres_t *pres, int expires, str *contact)
|
|
{
|
|
db_key_t q_cols[3], u_cols[4];
|
|
db_val_t q_vals[3], u_vals[4];
|
|
int n_query_cols = 0, n_update_cols = 0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
u_cols[n_update_cols] = &str_desired_expires_col;
|
|
u_vals[n_update_cols].type = DB1_INT;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.int_val = pres->desired_expires;
|
|
n_update_cols++;
|
|
|
|
u_cols[n_update_cols] = &str_expires_col;
|
|
u_vals[n_update_cols].type = DB1_INT;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.int_val = expires + (int) time(NULL);
|
|
n_update_cols++;
|
|
|
|
u_cols[n_update_cols] = &str_cseq_col;
|
|
u_vals[n_update_cols].type = DB1_INT;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.int_val = pres->cseq;
|
|
n_update_cols++;
|
|
|
|
u_cols[n_update_cols] = &str_remote_contact_col;
|
|
u_vals[n_update_cols].type = DB1_STR;
|
|
u_vals[n_update_cols].nul = 0;
|
|
u_vals[n_update_cols].val.str_val.s = contact->s;
|
|
u_vals[n_update_cols].val.str_val.len = contact->len;
|
|
n_update_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.update(pua_db, q_cols, 0, q_vals, u_cols, u_vals,
|
|
n_query_cols, n_update_cols) < 0)
|
|
{
|
|
LM_ERR("updating dialog\n");
|
|
return -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
int update_contact_puadb(ua_pres_t *pres, str *contact)
|
|
|
|
{
|
|
db_key_t q_cols[3], db_cols[1];
|
|
db_val_t q_vals[3], db_vals[1];
|
|
int n_query_cols= 0, n_update_cols=0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
/* we overwrite contact even if not changed */
|
|
db_cols[n_update_cols] = &str_remote_contact_col;
|
|
db_vals[n_update_cols].type = DB1_STR;
|
|
db_vals[n_update_cols].nul = 0;
|
|
db_vals[n_update_cols].val.str_val.s = contact->s;
|
|
db_vals[n_update_cols].val.str_val.len = contact->len;
|
|
n_update_cols++;
|
|
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
|
|
db_cols,db_vals,n_query_cols,n_update_cols) < 0)
|
|
{
|
|
LM_ERR("DB update failed\n");
|
|
return(-1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
int update_version_puadb(ua_pres_t *pres)
|
|
|
|
{
|
|
db_key_t q_cols[3], db_cols[1];
|
|
db_val_t q_vals[3], db_vals[1];
|
|
int n_query_cols= 0, n_update_cols=0;
|
|
|
|
if (pres==NULL)
|
|
{
|
|
LM_ERR("called with NULL param\n");
|
|
return(-1);
|
|
}
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[n_query_cols] = &str_call_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->call_id;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_to_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->to_tag;
|
|
n_query_cols++;
|
|
|
|
q_cols[n_query_cols] = &str_from_tag_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val = pres->from_tag;
|
|
n_query_cols++;
|
|
|
|
/* we overwrite contact even if not changed */
|
|
db_cols[n_update_cols] = &str_version_col;
|
|
db_vals[n_update_cols].type = DB1_INT;
|
|
db_vals[n_update_cols].nul = 0;
|
|
db_vals[n_update_cols].val.int_val = pres->version;
|
|
n_update_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return(-1);
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(-1);
|
|
}
|
|
|
|
if(pua_dbf.update(pua_db, q_cols, 0, q_vals,
|
|
db_cols,db_vals,n_query_cols,n_update_cols) < 0)
|
|
|
|
{
|
|
LM_ERR("DB update failed\n");
|
|
return(-1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
list_entry_t *get_subs_list_puadb(str *did)
|
|
{
|
|
list_entry_t *list = NULL;
|
|
db_key_t q_cols[1], res_cols[1];
|
|
db1_res_t *res= NULL;
|
|
db_val_t q_vals[1];
|
|
int n_query_cols= 0, n_res_cols = 0;
|
|
|
|
/* cols and values used for search query */
|
|
q_cols[n_query_cols] = &str_pres_id_col;
|
|
q_vals[n_query_cols].type = DB1_STR;
|
|
q_vals[n_query_cols].nul = 0;
|
|
q_vals[n_query_cols].val.str_val.s = did->s;
|
|
q_vals[n_query_cols].val.str_val.len = did->len;
|
|
n_query_cols++;
|
|
|
|
res_cols[n_res_cols] = &str_pres_uri_col;
|
|
n_res_cols++;
|
|
|
|
if(pua_db == NULL)
|
|
{
|
|
LM_ERR("null database connection\n");
|
|
return list;
|
|
}
|
|
|
|
if (pua_dbf.use_table(pua_db, &db_table) < 0)
|
|
{
|
|
LM_ERR("error in use_table pua\n");
|
|
return(list);
|
|
}
|
|
|
|
if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, q_cols, 0,
|
|
q_vals, res_cols, n_query_cols, n_res_cols, 0, &res) < 0)
|
|
{
|
|
LM_ERR("DB query error\n");
|
|
return list;
|
|
}
|
|
|
|
if (res == NULL)
|
|
{
|
|
LM_ERR("bad result\n");
|
|
return list;
|
|
}
|
|
|
|
if (RES_ROW_N(res) == 0)
|
|
{
|
|
LM_INFO( "No records found\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return list;
|
|
}
|
|
|
|
do {
|
|
int i, nr_rows;
|
|
db_row_t *rows;
|
|
nr_rows = RES_ROW_N(res);
|
|
rows = RES_ROWS(res);
|
|
|
|
for (i=0; i < nr_rows; i++)
|
|
{
|
|
str strng, *tmp_str;
|
|
strng.s = (char *) VAL_STRING(ROW_VALUES(rows+i));
|
|
strng.len = strlen(VAL_STRING(ROW_VALUES(rows+i)));
|
|
|
|
if ((tmp_str = (str *)pkg_malloc(sizeof(str))) == NULL)
|
|
{
|
|
LM_ERR("out of private memory\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return list;
|
|
}
|
|
if ((tmp_str->s = (char *)pkg_malloc(sizeof(char) * strng.len + 1)) == NULL)
|
|
{
|
|
pkg_free(tmp_str);
|
|
LM_ERR("out of private memory\n");
|
|
pua_dbf.free_result(pua_db, res);
|
|
return list;
|
|
}
|
|
memcpy(tmp_str->s, strng.s, strng.len);
|
|
tmp_str->len = strng.len;
|
|
tmp_str->s[tmp_str->len] = '\0';
|
|
|
|
list = list_insert(tmp_str, list, NULL);
|
|
}
|
|
} while ((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
|
|
&& (RES_ROWS(res)>0));
|
|
|
|
pua_dbf.free_result(pua_db, res);
|
|
|
|
return list;
|
|
}
|