int send_publish( publ_info_t* publ )
{
	str met = {"PUBLISH", 7};
	str* str_hdr = NULL;
	ua_pres_t* presentity= NULL;
	str* body= NULL;
	str* tuple_id= NULL;
	ua_pres_t* cb_param= NULL;
	unsigned int hash_code=0;
	str etag= {0, 0};
	int ver= 0;
	int result;
	int ret_code= 0;
	pua_event_t* ev= NULL;
	uac_req_t uac_r;
	db1_res_t *res=NULL;
	ua_pres_t dbpres; 
	str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
	int ret = -1;

	LM_DBG("pres_uri=%.*s\n", publ->pres_uri->len, publ->pres_uri->s );
	
	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	/* get event from list */
	ev= get_event(publ->event);
	if(ev== NULL)
	{
		LM_ERR("event not found in list\n");
		goto error;
	}	

	if (dbmode==PUA_DB_ONLY)
	{
		if (publ->etag) {
			memset(&dbpres, 0, sizeof(dbpres));
			dbpres.pres_uri = &pres_uri;
			dbpres.watcher_uri = &watcher_uri;
			dbpres.extra_headers = &extra_headers;
			presentity = get_record_puadb(publ->id, publ->etag,
						      &dbpres, &res);
		}
	}
	else
	{
		ua_pres_t pres;

		memset(&pres, 0, sizeof(ua_pres_t));
		pres.pres_uri = publ->pres_uri;
		pres.flag = publ->source_flag;
		pres.id = publ->id;
		pres.event = publ->event;
		if(publ->etag)
			pres.etag = *publ->etag;

		hash_code= core_hash(publ->pres_uri, NULL, HASH_SIZE);
		lock_get(&HashT->p_records[hash_code].lock);
		presentity= search_htable(&pres, hash_code);
	}

	if(publ->etag && presentity== NULL)
	{
		if (dbmode!=PUA_DB_ONLY) 
			lock_release(&HashT->p_records[hash_code].lock);
		ret = 418;
		goto error;
	}

	if(publ->flag & INSERT_TYPE)
	{
		LM_DBG("Insert flag set\n");
		goto insert;
	}
	
	if(presentity== NULL)
	{
insert:	
		if (dbmode!=PUA_DB_ONLY) 
			lock_release(&HashT->p_records[hash_code].lock);
		LM_DBG("insert type\n"); 
		
		if(publ->flag & UPDATE_TYPE )
		{
			LM_DBG("UPDATE_TYPE and no record found \n");
			publ->flag= INSERT_TYPE;
		}
		if(publ->expires== 0)
		{
			LM_DBG("request for a publish with expires 0 and"
					" no record found\n");
			goto done;
			
		}
		if(publ->body== NULL)
		{
			LM_ERR("New PUBLISH and no body found- invalid request\n");
			ret = ERR_PUBLISH_NO_BODY;
			goto error;
		}
	}
	else
	{
		LM_DBG("record found\n");
		publ->flag= UPDATE_TYPE;
		etag.s= (char*)pkg_malloc(presentity->etag.len* sizeof(char));
		if(etag.s== NULL)
		{
			LM_ERR("while allocating memory\n");
			if (dbmode!=PUA_DB_ONLY) 
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		memcpy(etag.s, presentity->etag.s, presentity->etag.len);
		etag.len= presentity->etag.len;

		if(presentity->tuple_id.s && presentity->tuple_id.len)
		{	
			/* get tuple_id*/
			tuple_id=(str*)pkg_malloc(sizeof(str));
			if(tuple_id== NULL)
			{
				LM_ERR("No more memory\n");
				if (dbmode!=PUA_DB_ONLY) 
					lock_release(&HashT->p_records[hash_code].lock);
				goto error;
			}	
			tuple_id->s= (char*)pkg_malloc(presentity->tuple_id.len* sizeof(char));
			if(tuple_id->s== NULL)
			{
				LM_ERR("No more memory\n");
				if (dbmode!=PUA_DB_ONLY) 
					lock_release(&HashT->p_records[hash_code].lock);
				goto error;
			}	
			memcpy(tuple_id->s, presentity->tuple_id.s, presentity->tuple_id.len);
			tuple_id->len= presentity->tuple_id.len;
		}

		if(publ->expires== 0)
		{
			LM_DBG("expires= 0- delete from hash table\n");
			if (dbmode!=PUA_DB_ONLY) 
				lock_release(&HashT->p_records[hash_code].lock);
			goto send_publish;
		}

		presentity->version++; 
		ver= presentity->version;

		if (dbmode==PUA_DB_ONLY)
		{ 
			update_version_puadb(presentity);
		}
		else
		{
			lock_release(&HashT->p_records[hash_code].lock);
		}
	}

	/* handle body */
	if(publ->body && publ->body->s)
	{
		ret_code= ev->process_body(publ, &body, ver, &tuple_id );
		if( ret_code< 0 || body== NULL)
		{
			LM_ERR("while processing body\n");
			if(body== NULL)
				LM_ERR("NULL body\n");
			goto error;
		}
	}
	if(tuple_id)
		LM_DBG("tuple_id= %.*s\n", tuple_id->len, tuple_id->s  );
	
send_publish:
	
	/* construct the callback parameter */
	if(etag.s && etag.len)
		publ->etag = &etag;

	cb_param= publish_cbparam(publ, body, tuple_id, REQ_OTHER);
	if(cb_param== NULL)
	{
		LM_ERR("constructing callback parameter\n");
		goto error;
	}

	if(publ->flag & UPDATE_TYPE)
		LM_DBG("etag:%.*s\n", etag.len, etag.s);
	str_hdr = publ_build_hdr((publ->expires< 0)?3600:publ->expires, ev, &publ->content_type, 
				(publ->flag & UPDATE_TYPE)?&etag:NULL, publ->extra_headers, (body)?1:0);

	if(str_hdr == NULL)
	{
		LM_ERR("while building extra_headers\n");
		goto error;
	}

	LM_DBG("publ->pres_uri:\n%.*s\n ", publ->pres_uri->len, publ->pres_uri->s);
	LM_DBG("str_hdr:\n%.*s %d\n ", str_hdr->len, str_hdr->s, str_hdr->len);
	if(body && body->len && body->s )
		LM_DBG("body:\n%.*s\n ", body->len, body->s);

	set_uac_req(&uac_r, &met, str_hdr, body, 0, TMCB_LOCAL_COMPLETED,
			publ_cback_func, (void*)cb_param);
	result= tmb.t_request(&uac_r,
			publ->pres_uri,			/*! Request-URI */
			publ->pres_uri,			/*! To */
 		        publ->pres_uri,			/*! From */
		        publ->outbound_proxy?
			      publ->outbound_proxy:&outbound_proxy /*! Outbound proxy*/
			);

	if(result< 0)
	{
		LM_ERR("in t_request tm module function\n");
		goto error;
	}

done:
	ret = 0;

	if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
	{
		if (pua_dbf.end_transaction(pua_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}
	goto finish;

error:
	if(cb_param)
		shm_free(cb_param);

	if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction)
	{
		if (pua_dbf.abort_transaction(pua_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

finish:
	if(etag.s)
		pkg_free(etag.s);

	if(body && ret_code)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}	
	if(str_hdr)
		pkg_free(str_hdr);
	if(tuple_id)
	{
		if(tuple_id->s)
			pkg_free(tuple_id->s);
		pkg_free(tuple_id);
	}
	free_results_puadb(res);

	return ret;
}
Exemple #2
0
int update_pua(ua_pres_t* p)
{
	str* str_hdr= NULL;
	int expires;
	int result;
	uac_req_t uac_r;
	int ret_code = 0;
	dlg_t* td = NULL;

	if(p->desired_expires== 0)
		expires= 3600;
	else
		expires= p->desired_expires- (int)time(NULL);

	if(p->watcher_uri == NULL || p->watcher_uri->len == 0)
	{
		str met= {"PUBLISH", 7};
		ua_pres_t* cb_param;

		str_hdr = publ_build_hdr(expires, get_event(p->event), NULL,
				&p->etag, p->extra_headers, 0);
		if(str_hdr == NULL)
		{
			LM_ERR("while building extra_headers\n");
			ret_code = -1;
			goto done;
		}
		LM_DBG("str_hdr:\n%.*s\n ", str_hdr->len, str_hdr->s);

		cb_param= build_uppubl_cbparam(p);
		if(cb_param== NULL)
		{
			LM_ERR("while constructing publ callback param\n");
			ret_code = -1;
			goto done;
		}	

		set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED,
				publ_cback_func, (void*)cb_param);
		result= tmb.t_request(&uac_r,
				p->pres_uri,					/* Request-URI */
				p->pres_uri,					/* To */
				p->pres_uri,					/* From */
				&outbound_proxy					/* Outbound proxy*/
				);
		if(result< 0)
		{
			LM_ERR("in t_request function\n"); 
			shm_free(cb_param);
			ret_code = -1;
			goto done;
		}
	}
	else
	{
		str met= {"SUBSCRIBE", 9};
		ua_pres_t* cb_param= NULL;

		td= pua_build_dlg_t(p);
		if(td== NULL)
		{
			LM_ERR("while building tm dlg_t structure");		
			ret_code = -1;
			goto done;
		};

		str_hdr= subs_build_hdr(&p->contact, expires,p->event,p->extra_headers);
		if(str_hdr== NULL || str_hdr->s== NULL)
		{
			if(p->event!=0)
				LM_ERR("while building extra headers\n");
			ret_code = -1;
			goto done;
		}
		cb_param= subs_cbparam_indlg(p, expires, REQ_ME);
		if(cb_param== NULL)
		{
			LM_ERR("while constructing subs callback param\n");
			ret_code = -1;
			goto done;
		}	

		set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED,
				subs_cback_func, (void*)cb_param);

		result= tmb.t_request_within(&uac_r);
		if(result< 0)
		{
			LM_ERR("in t_request function\n"); 
			shm_free(cb_param);
			ret_code = -1;
			goto done;
		}
	}
done:
	if(td!=NULL)
	{
		if(td->route_set)
			free_rr(&td->route_set);
		pkg_free(td);
		td= NULL;
	}
	if(str_hdr)
		pkg_free(str_hdr);

	return ret_code;

}
Exemple #3
0
int send_publish_int(ua_pres_t* presentity, publ_info_t* publ, pua_event_t* ev,
		int hash_index)
{
	unsigned long pres_id= 0;
	int ret = ERR_PUBLISH_GENERIC;
	char etag_buf[256];
	char tuple_buf[128];
	str tuple_id= {0, 0};
	str etag= {0, 0};
	int ver= 0;
	str* body= NULL;
	str* str_hdr = NULL;
	str met = {"PUBLISH", 7};

	LM_DBG("start\n");

	if(presentity)
	{
		LM_DBG("presentity exists\n");
		pres_id = PRES_HASH_ID(presentity);
		ver= ++presentity->version;

		/* copy etag */
		if(presentity->etag.s)
		{
			etag.s = etag_buf;
			memcpy(etag.s, presentity->etag.s, presentity->etag.len);
			etag.len = presentity->etag.len;
		}
		/* tuple id */
		if(presentity->tuple_id.s)
		{
			tuple_id.s = tuple_buf;
			memcpy(tuple_id.s, presentity->tuple_id.s, presentity->tuple_id.len);
			tuple_id.len = presentity->tuple_id.len;
		}
               presentity->desired_expires= publ->expires + (int)time(NULL);

		presentity->waiting_reply = 1;
		presentity->cb_param = publ->cb_param;

		if(publ->expires== 0)
		{
			LM_DBG("expires= 0- delete from hash table\n");
			delete_htable_safe(presentity, hash_index);
		}
	}
	lock_release(&HashT->p_records[hash_index].lock);

	/* handle body */
	if(publ->body && publ->body->s)
	{
		if(ev->process_body)
		{
			if(ev->process_body(publ, &body, ver, &tuple_id)< 0 || body== NULL)
			{
				LM_ERR("while processing body\n");
				goto error;
			}
		}
		else
			body = publ->body;
		LM_DBG("Handled body [%.*s]\n", body->len, body->s);
	}

	if(publ->expires!= 0 && publ->expires< min_expires)
		publ->expires = min_expires;

	if(presentity== NULL)
	{
		if(publ->expires== 0)
		{
			LM_DBG("request for a publish with expires 0 and"
					" no record found\n");
			ret = ERR_PUBLISH_NO_RECORD;
			goto error;
		}
		if(publ->body== NULL)
		{
			if (ev->content_type.s && ev->content_type.len) {
				LM_ERR("New '%.*s' PUBLISH and no body found - invalid request\n",
					ev->name.len, ev->name.s);
				ret = ERR_PUBLISH_NO_BODY;
				goto error;
			}
		}
		pres_id = new_publ_record(publ, ev, &tuple_id);
	}

	str_hdr = publ_build_hdr(((publ->expires< 0)?3600:publ->expires), ev, &publ->content_type,
				(etag.s?&etag:NULL), publ->extra_headers, ((body)?1:0));
	if(str_hdr == NULL)
	{
		LM_ERR("while building extra_headers\n");
		goto error;
	}

	LM_DBG("publ->pres_uri:\n%.*s\n ", publ->pres_uri->len, publ->pres_uri->s);
	LM_DBG("str_hdr:\n%.*s %d\n ", str_hdr->len, str_hdr->s, str_hdr->len);
	if(body && body->len && body->s )
		LM_DBG("body:\n%.*s\n ", body->len, body->s);

	LM_DBG("cback param = %ld\n", pres_id);

	tmb.t_request(&met,						/* Type of the message */
			publ->pres_uri,							/* Request-URI */
			publ->pres_uri,							/* To */
			publ->pres_uri,							/* From */
			str_hdr,								/* Optional headers */
			body,									/* Message body */
			((publ->outbound_proxy.s)?&publ->outbound_proxy:0),/*Outbound proxy*/
			publ->expires?publ_cback_func:0,		/* Callback function */
			(void*)pres_id,							/* Callback parameter */
			0
			);
	pkg_free(str_hdr);

	if(body && ev->process_body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}

	return ERR_PUBLISH_NO_ERROR;

error:
	if(body && ev->process_body)
	{
		if(body->s)
			xmlFree(body->s);
		pkg_free(body);
	}
	if(str_hdr)
		pkg_free(str_hdr);
	return ret;
}