예제 #1
0
파일: dlg_state.c 프로젝트: asyn/openvims
/**
 * Creates a new p_dialog structure.
 * Does not add the structure to the list.
 * @param call_id - call-id of the dialog
 * @param host - host that originates/terminates this dialog
 * @param port - port that originates/terminates this dialog
 * @param transport - transport that originates/terminates this dialog
 * @returns the new p_dialog* on success, or NULL on error;
 */
p_dialog* new_p_dialog(str call_id,str host,int port, int transport)
{
	p_dialog *d;
	
	if (!p_dialog_count_increment()) return 0;
	d = shm_malloc(sizeof(p_dialog));
	if (!d) {
		LOG(L_ERR,"ERR:"M_NAME":new_p_dialog(): Unable to alloc %d bytes\n",
			sizeof(p_dialog));
		goto error;
	}
	memset(d,0,sizeof(p_dialog));
	
	d->hash = get_p_dialog_hash(call_id);		
	STR_SHM_DUP(d->call_id,call_id,"shm");
	STR_SHM_DUP(d->host,host,"shm");	
	d->port = port;
	d->transport = transport;
				
	return d;
error:
out_of_memory:
	if (d){
		if (d->call_id.s) shm_free(d->call_id.s);
		if (d->host.s) shm_free(d->host.s);
		shm_free(d);		
	}
	p_dialog_count_decrement();
	return 0;
}
예제 #2
0
파일: dlg_state.c 프로젝트: asyn/openvims
/**
 * Finds and returns a dialog from the hash table.
 * \note the table should be locked already for the call_id in the parameter
 * @param call_id - call_id of the dialog
 * @param dir - the direction
 * @returns the p_dialog* or NULL if not found
 */
p_dialog* get_p_dialog_dir_nolock(str call_id,enum p_dialog_direction dir)
{
	p_dialog *d=0;
	unsigned int hash = get_p_dialog_hash(call_id);

	d = p_dialogs[hash].head;
	while(d){
		if (d->direction == dir &&
			d->call_id.len == call_id.len &&
			strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
				return d;
			}
		d = d->next;
	}
	return 0;
}
예제 #3
0
파일: dlg_state.c 프로젝트: asyn/openvims
/**
 * Finds and returns a dialog from the hash table.
 * \note Locks the hash slot if ok! Call d_unlock(p_dialog->hash) when you are finished)
 * @param call_id - dialog's call_id
 * @param host - host that originates/terminates this dialog
 * @param port - port that originates/terminates this dialog
 * @param transport - transport that originates/terminates this dialog
 * @param dir - the direction of the dialog. if NULL, it doesn't matter
 * \note transport is ignored.
 */
p_dialog* get_p_dialog(str call_id,str host,int port, int transport,enum p_dialog_direction *dir)
{
	p_dialog *d=0;
	unsigned int hash = get_p_dialog_hash(call_id);

	d_lock(hash);
		d = p_dialogs[hash].head;
		while(d){
			if ((!dir || d->direction == *dir) &&
				d->port == port &&
/*				d->transport == transport &&*/
/* commented because of strange behaviour */
				d->host.len == host.len &&
				d->call_id.len == call_id.len &&
				strncasecmp(d->host.s,host.s,host.len)==0 &&
				strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
					return d;
				}
			d = d->next;
		}
	d_unlock(hash);
	return 0;
}
예제 #4
0
/**
 *	Decode a dialog from a binary data structure
 * @param x - binary data to decode from
 * @returns the p_dialog* where the data has been decoded
 */
p_dialog* bin_decode_p_dialog(bin_data *x)
{
	p_dialog *d=0;
	int len,i;
	str s;
	char c;
	unsigned char uc;
	
	len = sizeof(p_dialog);
	d = (p_dialog*) shm_malloc(len);
	if (!d) {
		LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len);
		goto error;
	}
	memset(d,0,len);

	if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->call_id),&s)) goto error;

	if (!bin_decode_uchar(x,	&uc)) goto error;
	d->direction = uc;

	if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->host),&s)) goto error;
	if (!bin_decode_ushort(x,	&d->port)) goto error;
	
	if (!bin_decode_uchar(x,	&uc)) goto error;
	d->transport = uc;

	if (!bin_decode_ushort(x,	&d->routes_cnt)) goto error;

	len = sizeof(str)*d->routes_cnt;
	d->routes = (str*) shm_malloc(len);
	if (!d) {
		LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len);
		goto error;
	}
	memset(d->routes,0,len);	
	for(i=0;i<d->routes_cnt;i++)
		if (!bin_decode_str(x,&s)||!str_shm_dup(d->routes+i,&s)) goto error;
	
	if (!bin_decode_char(x,	&c)) goto error;
	d->method = c;
	if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->method_str),&s)) goto error;
	
	if (!bin_decode_int(x,	&d->first_cseq)) goto error;
	if (!bin_decode_int(x,	&d->last_cseq)) goto error;

	if (!bin_decode_char(x,	&c)) goto error;
	d->state = c;
	
	if (!bin_decode_time_t(x,	&d->expires)) goto error;
	
	if (!bin_decode_time_t(x, &d->lr_session_expires)) goto error;
	if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->refresher),&s)) goto error;
	if (!bin_decode_uchar(x,&d->uac_supp_timer)) goto error;	

	if (!bin_decode_uchar(x, &d->is_releasing)) goto error;
	
	if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->pcc_session_id),&s)) goto error;
	
	if (!bin_decode_dlg_t(x,&(d->dialog_c))) goto error;
	if (!bin_decode_dlg_t(x,&(d->dialog_s))) goto error;
	
	d->hash = get_p_dialog_hash(d->call_id);		
	
	return d;
error:
	LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error while decoding (at %d (%04x)).\n",x->max,x->max);
	if (d) {
		if (d->call_id.s) shm_free(d->call_id.s);
		if (d->host.s) shm_free(d->host.s);
		if (d->routes_cnt){
			for(i=0;i<d->routes_cnt;i++)
				if (d->routes[i].s) shm_free(d->routes[i].s);
			shm_free(d->routes);
		}
		if (d->method_str.s) shm_free(d->method_str.s);
		if (d->refresher.s) shm_free(d->refresher.s);
		shm_free(d);
	}
	return 0;
}