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

📄 presentity.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Presence Agent, presentity structure and related functions * * $Id: presentity.c,v 1.2 2005/06/16 12:41:52 bogdan_iancu Exp $ * * Copyright (C) 2001-2003 FhG Fokus * Copyright (C) 2004 Jamey Hicks * * This file is part of openser, a free SIP server. * * openser 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 * * openser 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 "../../db/db.h"#include "../../dprint.h"#include "../../mem/shm_mem.h"#include "../../ut.h"#include "../../parser/parse_event.h"#include "paerrno.h"#include "dlist.h"#include "notify.h"#include "pdomain.h"#include "presentity.h"#include "ptime.h"#include "pa_mod.h"#include "location.h"extern int use_db;extern char *presentity_table;str pstate_name[PS_NSTATES] = {	{ "unknown", sizeof("unknown") - 1 },	{ "online", sizeof("online") - 1 },	{ "offline", sizeof("offline") - 1 },	{ "away", sizeof("away") - 1 },	{ "xaway", sizeof("xaway") - 1 },	{ "dnd", sizeof("dnd") - 1 },	{ "typing", sizeof("typing") - 1 },};int basic2status(str basic){	int i;	for ( i= 0; i < PS_NSTATES; i++ ) {		if (str_strcasecmp(&pstate_name[i], &basic) == 0) {			return i;		}	}	return 0;}str str_strdup(str string){	str new_string;	new_string.s = shm_malloc(string.len + 1);	new_string.len = string.len;	strncpy(new_string.s, string.s, string.len);	new_string.s[string.len] = 0;	return new_string;}/* * Create a new presentity but do not update database */int new_presentity_no_wb(struct pdomain *pdomain, str* _uri, presentity_t** _p){     presentity_t* presentity;     int size = 0;     if (!_uri || !_p) {	  paerrno = PA_INTERNAL_ERROR;	  LOG(L_ERR, "new_presentity(): Invalid parameter value\n");	  return -1;     }     size = sizeof(presentity_t) + _uri->len + 1;     presentity = (presentity_t*)shm_malloc(size);     if (!presentity) {	  paerrno = PA_NO_MEMORY;	  LOG(L_ERR, "new_presentity(): No memory left: size=%d\n", size);	  return -1;     }     memset(presentity, 0, sizeof(presentity_t));     presentity->uri.s = ((char*)presentity) + sizeof(presentity_t);     strncpy(presentity->uri.s, _uri->s, _uri->len);     presentity->uri.s[_uri->len] = 0;     presentity->uri.len = _uri->len;     presentity->pdomain = pdomain;     *_p = presentity;     LOG(L_ERR, "new_presentity_no_wb=%p for uri=%.*s\n", 	 presentity, presentity->uri.len, presentity->uri.s);     return 0;}/* * Create a new presentity */int new_presentity(struct pdomain *pdomain, str* _uri, presentity_t** _p){     presentity_t* presentity;     int size = 0;     if (!_uri || !_p) {	  paerrno = PA_INTERNAL_ERROR;	  LOG(L_ERR, "new_presentity(): Invalid parameter value\n");	  return -1;     }     size = sizeof(presentity_t) + _uri->len + 1;     presentity = (presentity_t*)shm_malloc(size);     if (!presentity) {	  paerrno = PA_NO_MEMORY;	  LOG(L_ERR, "new_presentity(): No memory left: size=%d\n", size);	  return -1;     }     memset(presentity, 0, sizeof(presentity_t));     presentity->uri.s = ((char*)presentity) + sizeof(presentity_t);     strncpy(presentity->uri.s, _uri->s, _uri->len);     presentity->uri.s[_uri->len] = 0;     presentity->uri.len = _uri->len;     presentity->pdomain = pdomain;     if (use_db) {	  db_key_t query_cols[4];	  db_op_t  query_ops[4];	  db_val_t query_vals[4];	  db_key_t result_cols[4];	  db_res_t *res;	  int n_query_cols = 0;	  int n_result_cols = 0;	  int presid_col;	  int presid = 0;	  query_cols[0] = "uri";	  query_ops[0] = OP_EQ;	  query_vals[0].type = DB_STR;	  query_vals[0].nul = 0;	  query_vals[0].val.str_val = presentity->uri;	  n_query_cols++;	  query_cols[n_query_cols] = "pdomain";	  query_ops[n_query_cols] = OP_EQ;	  query_vals[n_query_cols].type = DB_STR;	  query_vals[n_query_cols].nul = 0;	  query_vals[n_query_cols].val.str_val = *presentity->pdomain->name;	  n_query_cols++;	  result_cols[presid_col = n_result_cols++] = "presid";	  if (pa_dbf.use_table(pa_db, presentity_table) < 0) {		  LOG(L_ERR, "new_presentity: Error in use_table\n");		  return -1;	  }	  while (!presid) {	       if (pa_dbf.query (pa_db, query_cols, query_ops, query_vals,			     result_cols, n_query_cols, n_result_cols, 0, &res) < 0) {		    LOG(L_ERR, "new_presentity: Error while querying presentity\n");		    return -1;	       }	       if (res && res->n > 0) {		    /* fill in tuple structure from database query result */		    db_row_t *row = &res->rows[0];		    db_val_t *row_vals = ROW_VALUES(row);		    presid = presentity->presid = row_vals[presid_col].val.int_val;		    LOG(L_INFO, "  presid=%d\n", presid);	       } else {		    /* insert new record into database */		    LOG(L_INFO, "new_presentity: inserting %d cols into table\n", n_query_cols);		    if (pa_dbf.insert(pa_db, query_cols, query_vals, n_query_cols)					< 0) {			 LOG(L_ERR, "new_presentity: Error while inserting tuple\n");			 return -1;		    }	       }	       pa_dbf.free_result(pa_db, res);	  }     }     *_p = presentity;     LOG(L_ERR, "new_presentity=%p for uri=%.*s\n", 	 presentity, presentity->uri.len, presentity->uri.s);     return 0;}/* * Free all memory associated with a presentity */void free_presentity(presentity_t* _p){	watcher_t* ptr;	presence_tuple_t *tuple;	return;	while(_p->watchers) {		ptr = _p->watchers;		_p->watchers = _p->watchers->next;		free_watcher(ptr);	}	while(_p->winfo_watchers) {		ptr = _p->winfo_watchers;		_p->winfo_watchers = _p->winfo_watchers->next;		free_watcher(ptr);	}		while(_p->tuples) {		tuple = _p->tuples;		_p->tuples = _p->tuples->next;		free_presence_tuple(tuple);	}	shm_free(_p);}/* * Sync presentity to db if db is in use */int db_update_presentity(presentity_t* _p){     if (use_db) {	  presence_tuple_t *tuple;	  db_key_t query_cols[22];	  db_op_t query_ops[22];	  db_val_t query_vals[22];	  int n_selectors = 2;	  int n_updates = 2;	  int presid = _p->presid;	  for (tuple = _p->tuples; tuple; tuple = tuple->next) {	       n_selectors = 2;	       n_updates = 2;	       LOG(L_ERR, "db_update_presentity starting: use_place_table=%d presid=%d\n", use_place_table, presid);	       query_cols[0] = "presid";	       query_ops[0] = OP_EQ;	       query_vals[0].type = DB_INT;	       query_vals[0].nul = 0;	       query_vals[0].val.int_val = presid;	       query_cols[1] = "contact";	       query_ops[1] = OP_EQ;	       query_vals[1].type = DB_STR;	       query_vals[1].nul = 0;	       query_vals[1].val.str_val.s = tuple->contact.s;	       query_vals[1].val.str_val.len = tuple->contact.len;	       LOG(L_ERR, "db_update_presentity:  tuple->contact=%.*s len=%d\n basic=%d expires=%ld priority=%f", 		   tuple->contact.len, tuple->contact.s, tuple->contact.len, tuple->state,		   tuple->expires, tuple->priority);	       {		    int n_query_cols = 2;		    LOG(L_INFO, "db_update_presentity: cleaning contact from table\n");		    if (pa_dbf.use_table(pa_db, presentity_contact_table) < 0) {			    LOG(L_ERR, "db_update_presentity: Error in use_table\n");			    return -1;		    }		    if (pa_dbf.delete(pa_db, query_cols, query_ops, query_vals,				      n_query_cols) < 0) {			 LOG(L_ERR, "db_update_presentity: Error while deleting tuple\n");			 return -1;		    }		    if (tuple->state == PS_OFFLINE)			 continue;	       }	       query_cols[n_updates] = "basic";	       query_vals[n_updates].type = DB_STR;	       query_vals[n_updates].nul = 0;	       query_vals[n_updates].val.str_val.s = pstate_name[tuple->state].s;	       query_vals[n_updates].val.str_val.len = strlen(pstate_name[tuple->state].s);	       n_updates++;	       query_cols[n_updates] = "tupleid";	       query_vals[n_updates].type = DB_STR;	       query_vals[n_updates].nul = 0;	       query_vals[n_updates].val.str_val.s = tuple->id.s;	       query_vals[n_updates].val.str_val.len = tuple->id.len;	       n_updates++;	       if (use_place_table) {		    int placeid = 0;		    LOG(L_ERR, "db_update_presentity: room=%.*s loc=%.*s\n", 			tuple->location.room.len, tuple->location.room.s,			tuple->location.loc.len, tuple->location.loc.s);		    		    if (tuple->location.room.len && tuple->location.room.s) {			 location_lookup_placeid(&tuple->location.room, &placeid);		    } else if (tuple->location.loc.len && tuple->location.loc.s) {			 location_lookup_placeid(&tuple->location.loc, &placeid);		    }		    if (placeid) {			 query_cols[n_updates] = "placeid";			 query_vals[n_updates].type = DB_INT;			 query_vals[n_updates].nul = 0;			 query_vals[n_updates].val.int_val = placeid;			 n_updates++;		    }	       } else {		    if (tuple->location.loc.len && tuple->location.loc.s) {			 query_cols[n_updates] = "location";			 query_vals[n_updates].type = DB_STR;			 query_vals[n_updates].nul = 0;			 query_vals[n_updates].val.str_val = tuple->location.loc;			 LOG(L_ERR, "db_update_presentity:  tuple->location.loc=%s len=%d\n", 			     tuple->location.loc.s, tuple->location.loc.len);			 n_updates++;		    }		    if (tuple->location.site.len && tuple->location.site.s) {			 query_cols[n_updates] = "site";			 query_vals[n_updates].type = DB_STR;			 query_vals[n_updates].nul = 0;			 query_vals[n_updates].val.str_val = tuple->location.site;			 n_updates++;		    }		    if (tuple->location.floor.len && tuple->location.floor.s) {			 query_cols[n_updates] = "floor";			 query_vals[n_updates].type = DB_STR;			 query_vals[n_updates].nul = 0;			 query_vals[n_updates].val.str_val = tuple->location.floor;			 n_updates++;		    }		    if (tuple->location.room.len && tuple->location.room.s) {			 query_cols[n_updates] = "room";			 query_vals[n_updates].type = DB_STR;			 query_vals[n_updates].nul = 0;			 query_vals[n_updates].val.str_val = tuple->location.room;			 n_updates++;		    }	       }	       if (tuple->location.x != 0) {		    query_cols[n_updates] = "x";		    query_vals[n_updates].type = DB_DOUBLE;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.double_val = tuple->location.x;		    n_updates++;	       }	       if (tuple->location.y != 0) {		    query_cols[n_updates] = "y";		    query_vals[n_updates].type = DB_DOUBLE;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.double_val = tuple->location.y;		    n_updates++;	       }	       if (tuple->location.radius != 0) {		    query_cols[n_updates] = "radius";		    query_vals[n_updates].type = DB_DOUBLE;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.double_val = tuple->location.radius;		    n_updates++;	       }	       if (tuple->priority != 0.0) {		    query_cols[n_updates] = "priority";		    query_vals[n_updates].type = DB_DOUBLE;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.double_val = tuple->priority;		    n_updates++;	       }	       if (tuple->expires != 0) {		    query_cols[n_updates] = "expires";		    query_vals[n_updates].type = DB_DATETIME;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.time_val = tuple->expires;		    n_updates++;	       }	       if (tuple->prescaps != 0) {		    query_cols[n_updates] = "prescaps";		    query_vals[n_updates].type = DB_INT;		    query_vals[n_updates].nul = 0;		    query_vals[n_updates].val.int_val = tuple->prescaps;		    n_updates++;	       }	       if (n_updates > (sizeof(query_cols)/sizeof(db_key_t)))		    LOG(L_ERR, "too many update values. n_selectors=%d, n_updates=%d "					"dbf.update=%p\n", 			n_selectors, n_updates, pa_dbf.update);	       if (pa_dbf.use_table(pa_db, presentity_contact_table) < 0) {		       LOG(L_ERR, "db_update_presentity: Error in use_table\n");		       return -1;	       }	       if (pa_dbf.insert(pa_db, query_cols, query_vals, n_updates) < 0) {		    LOG(L_ERR, "db_update_presentity: Error while updating database\n");		    return -1;	       }	  }     }     return 0;}/* * Create a new presence_tuple */int new_presence_tuple(str* _contact, time_t expires, presentity_t *_p, presence_tuple_t ** _t){     presence_tuple_t* tuple;     int size = 0;     int r;     if (!_contact || !_t) {	  paerrno = PA_INTERNAL_ERROR;	  LOG(L_ERR, "new_presence_tuple(): Invalid parameter value\n");	  return -1;     }     size = sizeof(presence_tuple_t) + _contact->len + 1;     tuple = (presence_tuple_t*)shm_malloc(size);     if (!tuple) {	  paerrno = PA_NO_MEMORY;	  LOG(L_ERR, "new_presence_tuple(): No memory left: size=%d\n", size);	  return -1;     }     memset(tuple, 0, sizeof(presence_tuple_t));     tuple->state = PS_UNKNOWN;     tuple->contact.s = ((char*)tuple) + sizeof(presence_tuple_t);     tuple->status.s = tuple->status_buf;     strncpy(tuple->contact.s, _contact->s, _contact->len);     _contact->s[_contact->len] = 0;     tuple->contact.len = _contact->len;     tuple->location.loc.s = tuple->location.loc_buf;     tuple->location.site.s = tuple->location.site_buf;     tuple->location.floor.s = tuple->location.floor_buf;     tuple->location.room.s = tuple->location.room_buf;     tuple->location.packet_loss.s = tuple->location.packet_loss_buf;     tuple->id.s = tuple->id_buf;     tuple->expires = expires;     tuple->priority = default_priority;     r = rand();     tuple->id.len = sprintf(tuple->id.s, "tid%x", r);     *_t = tuple;     LOG(L_ERR, "new_tuple=%p for aor=%.*s contact=%.*s\n", tuple, 	 _p->uri.len, _p->uri.s,	 tuple->contact.len, tuple->contact.s);	     return 0;}/* * Find a presence_tuple for contact _contact on presentity _p */int find_presence_tuple(str* _contact, presentity_t *_p, presence_tuple_t ** _t){	presence_tuple_t *tuple;	if (!_contact || !_contact->len || !_p || !_t) {		paerrno = PA_INTERNAL_ERROR;		LOG(L_ERR, "find_presence_tuple(): Invalid parameter value\n");		return -1;	}	tuple = _p->tuples;	//LOG(L_ERR, "find_presence_tuple: _p=%p _p->tuples=%p\n", _p, _p->tuples);

⌨️ 快捷键说明

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