⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avp_db.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
字号:
/* * $Id: avp_db.c,v 1.2.2.1 2005/04/20 19:56:26 bogdan Exp $ * * Copyright (C) 2004 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 <string.h>#include "../../sr_module.h"#include "../../mem/mem.h"#include "../../parser/msg_parser.h"#include "../../parser/hf.h"#include "../../parser/parse_from.h"#include "../../parser/parse_to.h"#include "../../parser/parse_uri.h"#include "../../str.h"#include "../../db/db.h"#include "../../config.h"#include "../../usr_avp.h"MODULE_VERSION#define CALLER_PREFIX "caller_"#define CALLER_PREFIX_LEN (sizeof(CALLER_PREFIX) - 1)#define CALLEE_PREFIX "callee_"#define CALLEE_PREFIX_LEN (sizeof(CALLEE_PREFIX) - 1)typedef enum load_avp_param {	LOAD_CALLER_UUID,  /* Use the caller's UUID as the key */	LOAD_CALLEE_UUID,  /* Use the callee's UUID as the key */	LOAD_CALLER,       /* Use the caller's username and domain as the key */	LOAD_CALLEE        /* Use the callee's username and domain as the key */} load_avp_param_t;static char* db_url          = DEFAULT_RODB_URL;    /* Database URL */static char* db_table        = "usr_preferences";static char* uuid_column     = "uuid";static char* username_column = "username";static char* domain_column   = "domain";static char* attr_column     = "attribute";static char* val_column      = "value";static str caller_prefix     = {CALLER_PREFIX, CALLER_PREFIX_LEN};static str callee_prefix     = {CALLEE_PREFIX, CALLEE_PREFIX_LEN};static int caller_uuid_avp   = 1;static int callee_uuid_avp   = 2;static int use_domain        = 0;static db_con_t* db_handle;static db_func_t dbf;static int load_avp(struct sip_msg*, char*, char*);static int mod_init(void);static int child_init(int);static int load_avp_fixup(void**, int);/* * Exported functions */static cmd_export_t cmds[] = {	{"avp_load", load_avp, 1, load_avp_fixup, REQUEST_ROUTE | FAILURE_ROUTE},	{0, 0, 0, 0, 0}};/* * Exported parameters */static param_export_t params[] = {	{"caller_uuid_avp", INT_PARAM, &caller_uuid_avp},	{"callee_uuid_avp", INT_PARAM, &callee_uuid_avp},	{"db_url",          STR_PARAM, &db_url         },	{"pref_table",      STR_PARAM, &db_table       },	{"uuid_column",     STR_PARAM, &uuid_column    },	{"username_column", STR_PARAM, &username_column},	{"domain_column",   STR_PARAM, &domain_column  },	{"attr_column",     STR_PARAM, &attr_column    },	{"val_column",      INT_PARAM, &val_column     },	{"use_domain",      INT_PARAM, &use_domain     },	{0, 0, 0}};struct module_exports exports = {	"avp_db",	cmds,        /* Exported commands */	params,      /* Exported parameters */	mod_init,    /* module initialization function */	0,           /* response function*/	0,           /* destroy function */	0,           /* oncancel function */	child_init   /* per-child init function */};static int mod_init(void){        DBG("avp_db - initializing\n");	if (bind_dbmod(db_url, &dbf) < 0) {		LOG(L_ERR, "avpdb_mod_init: Unable to bind a database driver\n");		return -1;	}	if (!DB_CAPABILITY(dbf, DB_CAP_QUERY)) {		LOG(L_ERR, "avpdb_mod_init: Selected database driver does not suppor the query capability\n");		return -1;	}	caller_prefix.len = strlen(caller_prefix.s);	callee_prefix.len = strlen(callee_prefix.s);            return 0;}static int child_init(int rank){	DBG("avp_db - Initializing child %i\n", rank);	db_handle = dbf.init(db_url);		if (!db_handle) {		LOG(L_ERR, "avpdb_init_child: could not initialize connection to %s\n",  db_url);		return -1;	}		return 0;}static int query_db(str* prefix, str* uuid, str* username, str* domain){	int name_len, err = -1;		db_key_t  cols[2], keys[2];	db_val_t  vals[2];	db_res_t* res;	db_row_t* cur_row;		int_str name, val;	str name_str, val_str;	cols[0] = attr_column;	cols[1] = val_column;		if (uuid) {		keys[0] = uuid_column;		VAL_TYPE(vals) = DB_STR;		VAL_NULL(vals) = 0;		VAL_STR(vals)  = *uuid;	} else {		keys[0] = username_column;		VAL_TYPE(vals) = DB_STR;		VAL_NULL(vals) = 0;		VAL_STR(vals) = *username;	}	if (use_domain) {		keys[1] = domain_column;		VAL_TYPE(vals + 1) = DB_STR;		VAL_NULL(vals + 1) = 0;		VAL_STR(vals + 1) = *domain;	}		if (dbf.use_table(db_handle, db_table) < 0) {		LOG(L_ERR, "query_db: Unable to change the table\n");	}	err = dbf.query(db_handle, keys, 0, vals, cols, (use_domain ? 2 : 1), 2, 0, &res);	if (err) {		LOG(L_ERR,"query_db: db_query failed.");		return -1;	}		name.s = &name_str;	val.s  = &val_str;	for (cur_row = res->rows; cur_row < res->rows + res->n; cur_row++) {		if (VAL_NULL(ROW_VALUES(cur_row)) || VAL_NULL(ROW_VALUES(cur_row) + 1)) {			continue;		}		name_len = strlen((char*)VAL_STRING(ROW_VALUES(cur_row)));		name_str.len = prefix->len + name_len;		name_str.s = pkg_malloc(name_str.len);		if (name_str.s == 0) {			LOG(L_ERR, "query_db: Out of memory");			dbf.free_result(db_handle, res);			return -1;		}		    		memcpy(name_str.s, prefix->s, prefix->len);		memcpy(name_str.s + prefix->len, 		       (char*)VAL_STRING(ROW_VALUES(cur_row)), name_len);			val_str.len = strlen((char*)VAL_STRING(ROW_VALUES(cur_row) + 1));		val_str.s = (char*)VAL_STRING(ROW_VALUES(cur_row) + 1);				err = add_avp(AVP_NAME_STR | AVP_VAL_STR, name, val);		if (err != 0) {			LOG(L_ERR, "query_db: add_avp failed\n");			pkg_free(name_str.s);			dbf.free_result(db_handle, res);		}			DBG("query_db: AVP '%.*s'='%.*s' has been added\n", name_str.len, 		    name_str.s,		    val_str.len,		    val_str.s);	}		dbf.free_result(db_handle, res);	return 1;}static int load_avp_uuid(struct sip_msg* msg, str* prefix, int avp_id){	struct usr_avp *uuid;	int_str attr_istr, val_istr;	attr_istr.n = avp_id;		uuid = search_first_avp(AVP_NAME_STR, attr_istr, &val_istr);	if (!uuid) {		LOG(L_ERR, "load_avp_uuid: no AVP with id %d was found\n", avp_id);		return -1;	}		if (!(uuid->flags & AVP_VAL_STR)) {		LOG(L_ERR, "load_avp_uuid: value for <%d> should "		    "be of type string\n", avp_id);		return -1;	}		return query_db(prefix, val_istr.s, 0, 0);}static int load_avp_user(struct sip_msg* msg, str* prefix, load_avp_param_t param){	str* uri;	struct sip_uri puri;	if (param == LOAD_CALLER) {		if (parse_from_header(msg) < 0) {			LOG(L_ERR, "load_avp_user: Error while parsing From header field\n");			return -1;		}		uri = &get_from(msg)->uri;		if (parse_uri(uri->s, uri->len, &puri) == -1) {			LOG(L_ERR, "load_avp_user: Error while parsing From URI\n");			return -1;		}		return query_db(prefix, 0, &puri.user, &puri.host);	} else if (param == LOAD_CALLEE) {		if (parse_sip_msg_uri(msg) < 0) {			LOG(L_ERR, "load_avp_user: Request-URI parsing failed\n");			return -1;		}		if (msg->parsed_uri_ok != 1) {			LOG(L_ERR, "load_avp_user: Unable to parse Request-URI\n");			return -1;		}		return query_db(prefix, 0, &msg->parsed_uri.user, &msg->parsed_uri.host);	} else {		LOG(L_ERR, "load_avp_user: Unknown header field type\n");		return -1;	}}static int load_avp(struct sip_msg* msg, char* attr, char* _dummy){	switch((load_avp_param_t)attr) {	case LOAD_CALLER_UUID:		return load_avp_uuid(msg, &caller_prefix, caller_uuid_avp);		break;	case LOAD_CALLEE_UUID:		return load_avp_uuid(msg, &callee_prefix, callee_uuid_avp);		break;	case LOAD_CALLER:		return load_avp_user(msg, &caller_prefix, LOAD_CALLER);		break;	case LOAD_CALLEE:		return load_avp_user(msg, &callee_prefix, LOAD_CALLEE);		break;			default:		LOG(L_ERR, "load_avp: Unknown parameter value\n");		return -1;	}}static int load_avp_fixup(void** param, int param_no){	long id = 0;	if (param_no == 1) {		if (!strcasecmp(*param, "caller_uuid")) {			id = LOAD_CALLER_UUID;		} else if (!strcasecmp(*param, "callee_uuid")) {			id = LOAD_CALLEE_UUID;		} else if (!strcasecmp(*param, "caller")) {			id = LOAD_CALLER;		} else if (!strcasecmp(*param, "callee")) {			id = LOAD_CALLEE;		} else {			LOG(L_ERR, "load_avp_fixup: Unknown parameter\n");			return -1;		}	}	pkg_free(*param);	*param=(void*)id;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -