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

📄 ucontact.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * $Id: ucontact.c,v 1.32.2.4 2005/07/27 12:40:31 janakj Exp $  * * Usrloc contact structure * * Copyright (C) 2001-2003 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 * * History: * --------- * 2003-03-12 added replication mark and three zombie states (nils) * 2004-03-17 generic callbacks added (bogdan) * 2004-06-07 updated to the new DB api (andrei) */#include "ucontact.h"#include <string.h>             /* memcpy */#include "../../mem/shm_mem.h"#include "../../ut.h"#include "../../dprint.h"#include "../../db/db.h"#include "ul_mod.h"#include "ul_callback.h"/* * Create a new contact structure */int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, qvalue_t _q,		 str* _callid, int _cseq, unsigned int _flags, ucontact_t** _c, str* _ua, str* _recv){	*_c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));	if (!(*_c)) {	        LOG(L_ERR, "new_ucontact(): No memory left\n");		return -1;	}	memset(*_c, 0, sizeof(ucontact_t));	(*_c)->domain = _dom;	(*_c)->aor = _aor;	(*_c)->c.s = (char*)shm_malloc(_contact->len);	if ((*_c)->c.s == 0) {		LOG(L_ERR, "new_ucontact(): No memory left 2\n");		goto error;	}	memcpy((*_c)->c.s, _contact->s, _contact->len);	(*_c)->c.len = _contact->len;	(*_c)->expires = _e;	(*_c)->q = _q;	(*_c)->callid.s = (char*)shm_malloc(_callid->len);	if ((*_c)->callid.s == 0) {		LOG(L_ERR, "new_ucontact(): No memory left 4\n");		goto error;	}	memcpy((*_c)->callid.s, _callid->s, _callid->len);	(*_c)->callid.len = _callid->len;	(*_c)->user_agent.s = (char*)shm_malloc(_ua->len);	if ((*_c)->user_agent.s == 0) {		LOG(L_ERR, "new_ucontact(): No memory left 8\n");		goto error;	}	memcpy((*_c)->user_agent.s, _ua->s, _ua->len);	(*_c)->user_agent.len = _ua->len;	if (_recv) {		(*_c)->received.s = (char*)shm_malloc(_recv->len);		if ((*_c)->received.s == 0) {			LOG(L_ERR, "new_ucontact(): No memory left\n");			goto error;		}		memcpy((*_c)->received.s, _recv->s, _recv->len);		(*_c)->received.len = _recv->len;	} else {		(*_c)->received.s = 0;		(*_c)->received.len = 0;	}	(*_c)->cseq = _cseq;	(*_c)->state = CS_NEW;	(*_c)->flags = _flags;        return 0; error:	if (*_c) {		if ((*_c)->received.s) shm_free((*_c)->received.s);		if ((*_c)->user_agent.s) shm_free((*_c)->user_agent.s);		if ((*_c)->callid.s) shm_free((*_c)->callid.s);		if ((*_c)->c.s) shm_free((*_c)->c.s);		shm_free(*_c);	}	return -1;}	/* * Free all memory associated with given contact structure */void free_ucontact(ucontact_t* _c){	if (!_c) return;	if (_c->received.s) shm_free(_c->received.s);	if (_c->user_agent.s) shm_free(_c->user_agent.s);	if (_c->callid.s) shm_free(_c->callid.s);	if (_c->c.s) shm_free(_c->c.s);	shm_free(_c);}/* * Print contact, for debugging purposes only */void print_ucontact(FILE* _f, ucontact_t* _c){	time_t t = time(0);	char* st;	switch(_c->state) {	case CS_NEW:   st = "CS_NEW";     break;	case CS_SYNC:  st = "CS_SYNC";    break;	case CS_DIRTY: st = "CS_DIRTY";   break;	default:       st = "CS_UNKNOWN"; break;	}	fprintf(_f, "~~~Contact(%p)~~~\n", _c);	fprintf(_f, "domain    : '%.*s'\n", _c->domain->len, ZSW(_c->domain->s));	fprintf(_f, "aor       : '%.*s'\n", _c->aor->len, ZSW(_c->aor->s));	fprintf(_f, "Contact   : '%.*s'\n", _c->c.len, ZSW(_c->c.s));	fprintf(_f, "Expires   : ");	if (_c->flags & FL_PERMANENT) {		fprintf(_f, "Permanent\n");	} else {		if (_c->expires == 0) {			fprintf(_f, "Deleted\n");		} else if (t > _c->expires) {			fprintf(_f, "Expired\n");		} else {			fprintf(_f, "%u\n", (unsigned int)(_c->expires - t));		}	}	fprintf(_f, "q         : %s\n", q2str(_c->q, 0));	fprintf(_f, "Call-ID   : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s));	fprintf(_f, "CSeq      : %d\n", _c->cseq);	fprintf(_f, "User-Agent: '%.*s'\n", _c->user_agent.len, ZSW(_c->user_agent.s));	fprintf(_f, "received  : '%.*s'\n", _c->received.len, ZSW(_c->received.s));	fprintf(_f, "State     : %s\n", st);	fprintf(_f, "Flags     : %u\n", _c->flags);	fprintf(_f, "next      : %p\n", _c->next);	fprintf(_f, "prev      : %p\n", _c->prev);	fprintf(_f, "~~~/Contact~~~~\n");}/* * Update ucontact structure in memory */int mem_update_ucontact(ucontact_t* _c, time_t _e, qvalue_t _q, str* _cid, int _cs,			unsigned int _set, unsigned int _res, str* _ua, str* _recv){	char* ptr;		if (_c->callid.len < _cid->len) {		ptr = (char*)shm_malloc(_cid->len);		if (ptr == 0) {			LOG(L_ERR, "update_ucontact(): No memory left\n");			return -1;		}				memcpy(ptr, _cid->s, _cid->len);		shm_free(_c->callid.s);		_c->callid.s = ptr;	} else {		memcpy(_c->callid.s, _cid->s, _cid->len);	}	_c->callid.len = _cid->len;	if (_c->user_agent.len < _ua->len) {		ptr = (char*)shm_malloc(_ua->len);		if (ptr == 0) {			LOG(L_ERR, "update_ucontact(): No memory left\n");			return -1;		}		memcpy(ptr, _ua->s, _ua->len);		shm_free(_c->user_agent.s);		_c->user_agent.s = ptr;	} else {		memcpy(_c->user_agent.s, _ua->s, _ua->len);	}	_c->user_agent.len = _ua->len;	if (_recv) {		if (_c->received.len < _recv->len) {			ptr = (char*)shm_malloc(_recv->len);			if (ptr == 0) {				LOG(L_ERR, "update_ucontact(): No memory left\n");				return -1;			}			memcpy(ptr, _recv->s, _recv->len);			/* previous received might be NULL! -bogdan */			if (_c->received.s)				shm_free(_c->received.s);			_c->received.s = ptr;		} else {			memcpy(_c->received.s, _recv->s, _recv->len);		}		_c->received.len = _recv->len;	} else {		if (_c->received.s) shm_free(_c->received.s);		_c->received.s = 0;		_c->received.len = 0;	}	_c->expires = _e;	_c->q = _q;	_c->cseq = _cs;	_c->flags |= _set;	_c->flags &= ~_res;	return 0;}/* ================ State related functions =============== *//* * Update state of the contact */void st_update_ucontact(ucontact_t* _c){	switch(_c->state) {	case CS_NEW:		     /* Contact is new and is not in the database yet,		      * we remain in the same state here because the		      * contact must be inserted later in the timer		      */		break;	case CS_SYNC:		     /* For db mode 2 a modified contact needs to be 			  * updated also in the database, so transit into 			  * CS_DIRTY and let the timer to do the update 			  * again. For db mode 1 the db update is already			  * done and we don't have to change the state.		      */		if (db_mode == WRITE_BACK) {			_c->state = CS_DIRTY;		}		break;	case CS_DIRTY:		     /* Modification of dirty contact results in		      * dirty contact again, don't change anything		      */		break;	}}/* * Update state of the contact * Returns 1 if the contact should be * delete from memory immediately, * 0 otherwise */int st_delete_ucontact(ucontact_t* _c){	switch(_c->state) {	case CS_NEW:		     /* Contact is new and isn't in the database		      * yet, we can delete it from the memory		      * safely.		      */		return 1;	case CS_SYNC:	case CS_DIRTY:		     /* Contact is in the database,		      * we cannot remove it from the memory 		      * directly, but we can set expires to zero		      * and the timer will take care of deleting 		      * the contact from the memory as well as 		      * from the database		      */		if (db_mode == WRITE_BACK) {			     /* Reset permanent flag */			_c->flags &= ~FL_PERMANENT;			_c->expires = 0;			return 0;		} else {			     /* WRITE_THROUGH or NO_DB -- we can			      * remove it from memory immediately and			      * the calling function would also remove			      * it from the database if needed			      */			return 1;		}	}	return 0; /* Makes gcc happy */}/* * Called when the timer is about to delete * an expired contact, this routine returns * 1 if the contact should be removed from * the database and 0 otherwise */

⌨️ 快捷键说明

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