Ejemplo n.º 1
0
/*! \brief Relay a MESSAGE to a SIP client 
	\todo This assumes that a message is text/plain, which is not always the case with
		XMPP messages. We should propably also set the character set, as all
		SIP clients doesn't assume utf8 for text/plain
*/
int xmpp_send_sip_msg(char *from, char *to, char *msg)
{
	str msg_type = { "MESSAGE", 7 };
	str hdr, fromstr, tostr, msgstr;
	char buf[512];
	uac_req_t uac_r;
	
	hdr.s = buf;
	hdr.len = snprintf(buf, sizeof(buf),
			"Content-type: text/plain" CRLF "Contact: %s" CRLF, from);

	fromstr.s = from;
	fromstr.len = strlen(from);
	tostr.s = to;
	tostr.len = strlen(to);
	msgstr.s = msg;
	msgstr.len = strlen(msg);

	set_uac_req(&uac_r, &msg_type, &hdr, &msgstr, 0, 0, 0, 0);
	return tmb.t_request(
			&uac_r,
			0,							/*!< Request-URI */
			&tostr,							/*!< To */
			&fromstr,						/*!< From */
			(outbound_proxy.s)?&outbound_proxy:NULL/* Outbound proxy*/
			);
}
Ejemplo n.º 2
0
int imc_handle_unknown(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst)
{
	str body;
	uac_req_t uac_r;

	body.s   = imc_body_buf;
	body.len = snprintf(body.s, IMC_BUF_SIZE,
		"invalid command '%.*s' - send ''%.*shelp' for details",
		cmd->name.len, cmd->name.s, imc_cmd_start_str.len, imc_cmd_start_str.s);

	if(body.len<0 || body.len>=IMC_BUF_SIZE)
	{
		LM_ERR("unable to print message\n");
		return -1;
	}

	LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s);
	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, 0, 0, 0);
	tmb.t_request(&uac_r,
				NULL,									/* Request-URI */
				src,									/* To */
				dst,									/* From */
				(outbound_proxy.s)?&outbound_proxy:NULL /* outbound proxy */
			);
	return 0;
}
Ejemplo n.º 3
0
/* Relay a MESSAGE to a SIP client */
int purple_send_sip_msg(char *to, char *from, char *msg) {
	LM_DBG("sending message from %s to %s\n", from, to);
	str msg_type = { "MESSAGE", 7 };
	str ruri, hdr, fromstr, tostr, msgstr;
	char hdr_buf[512], ruri_buf[512];
	uac_req_t uac_r;
	
	/* update the local config framework structures */
	cfg_update();

	ruri.s = ruri_buf;
	ruri.len = snprintf(ruri_buf, sizeof(ruri_buf), "%s;proto=purple", to);
	
	hdr.s = hdr_buf;
	hdr.len = snprintf(hdr_buf, sizeof(hdr_buf), "Content-type: text/plain" CRLF "Contact: %s" CRLF, from);

	fromstr.s = from;
	fromstr.len = strlen(from);
	tostr.s = to;
	tostr.len = strlen(to);
	msgstr.s = msg;
	msgstr.len = strlen(msg);

	set_uac_req(&uac_r, &msg_type, &hdr, &msgstr, 0, 0, 0, 0);
	if (tmb.t_request(&uac_r, &ruri, &tostr, &fromstr, 0) < 0) {
		LM_ERR("error sending request\n");
		return -1;
	}
	LM_DBG("message sent successfully\n");
	return 0;
}
Ejemplo n.º 4
0
    static int
sca_notify_subscriber_internal( sca_mod *scam, sca_subscription *sub,
	str *headers )
{
    uac_req_t		request;
    dlg_t		*dlg = NULL;
    int			rc = -1;

    dlg = sca_notify_dlg_for_subscription( sub );
    if ( dlg == NULL ) {
	LM_ERR( "Failed to create dlg_t for %s NOTIFY to %.*s",
		sca_event_name_from_type( sub->event ),
		STR_FMT( &sub->subscriber ));
	goto done;
    }

    set_uac_req( &request, (str *)&SCA_METHOD_NOTIFY, headers, NULL, dlg,
			TMCB_LOCAL_COMPLETED, sca_notify_reply_cb, scam );
    rc = scam->tm_api->t_request_within( &request );
    if ( rc < 0 ) {
	LM_ERR( "Failed to send in-dialog %s NOTIFY to %.*s",
		sca_event_name_from_type( sub->event ),
		STR_FMT( &sub->subscriber ));
    }
    /* fall through, return rc from t_request_within */

done:
    if ( dlg != NULL ) {
	pkg_free( dlg );
    }

    return( rc );
}
Ejemplo n.º 5
0
/**
 * send a SIP MESSAGE message
 * - to : destination
 * - from : origin
 * - contact : contact header
 * - msg : body of the message
 * return : 0 on success or <0 on error
 */
int xj_send_sip_msg(str *proxy, str *to, str *from, str *msg, int *cbp)
{
	str  msg_type = { "MESSAGE", 7};
	char buf[512];
	str  tfrom;
	str  str_hdr;
	char buf1[1024];
	uac_req_t uac_r;

	if( !to || !to->s || to->len <= 0 
			|| !from || !from->s || from->len <= 0 
			|| !msg || !msg->s || msg->len <= 0
			|| (cbp && *cbp!=0) )
		return -1;

	// from correction
	tfrom.len = 0;
	strncpy(buf+tfrom.len, "<sip:", 5);
	tfrom.len += 5;
	strncpy(buf+tfrom.len, from->s, from->len);
	tfrom.len += from->len;
	buf[tfrom.len++] = '>';
		
	tfrom.s = buf;
	
	// building Contact and Content-Type
	strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: ");
	str_hdr.len = 24 + CRLF_LEN + 9;
	
	strncat(buf1,tfrom.s,tfrom.len);
	str_hdr.len += tfrom.len;
	
	strcat(buf1, CRLF);
	str_hdr.len += CRLF_LEN;
	str_hdr.s = buf1;
	if(cbp)
	{
#ifdef XJ_EXTRA_DEBUG
		LM_DBG("uac callback parameter [%p==%d]\n", cbp, *cbp);
#endif
		set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, TMCB_LOCAL_COMPLETED,
				xj_tuac_callback, (void*)cbp);
	} else {
		set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, 0, 0, 0);		
	}
	return tmb.t_request(&uac_r, 0, to, &tfrom, 0);
}
Ejemplo n.º 6
0
/* send keep-alive
 * dlg - pointer to a struct dlg_cell
 * dir - direction: the request will be sent to:
 * 		DLG_CALLER_LEG (0): caller
 * 		DLG_CALLEE_LEG (1): callee
 */
int dlg_send_ka(dlg_cell_t *dlg, int dir, str *hdrs)
{
	uac_req_t uac_r;
	dlg_t* di;
	str met = {"OPTIONS", 7};
	int result;
	dlg_iuid_t *iuid = NULL;

	/* do not send KA request for non-confirmed dialogs (not supported) */
	if (dlg->state != DLG_STATE_CONFIRMED) {
		LM_DBG("skipping non-confirmed dialogs\n");
		return 0;
	}

	/* build tm dlg by direction */
	if ((di = build_dlg_t(dlg, dir)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto err;
	}

	/* tm increases cseq value, decrease it no to make it invalid
	 * - dialog is ended on timeout (408) or C/L does not exist (481) */
	if(di->loc_seq.value>1)
		di->loc_seq.value -= 2;
	else
		di->loc_seq.value -= 1;

	LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");

	iuid = dlg_get_iuid_shm_clone(dlg);
	if(iuid==NULL)
	{
		LM_ERR("failed to create dialog unique id clone\n");
		goto err;
	}

	memset(&uac_r,'\0', sizeof(uac_req_t));
	set_uac_req(&uac_r, &met, hdrs, NULL, di, TMCB_LOCAL_COMPLETED,
				dlg_ka_cb, (void*)iuid);
	result = d_tmb.t_request_within(&uac_r);

	if(result < 0){
		LM_ERR("failed to send the BYE request\n");
		goto err;
	}

	free_tm_dlg(di);

	LM_DBG("keep-alive sent to %s\n", (dir==0)?"caller":"callee");
	return 0;

err:
	if(di)
		free_tm_dlg(di);
	return -1;
}
Ejemplo n.º 7
0
static int dlg_refer_callee(dlg_transfer_ctx_t *dtc)
{
	/*verify direction*/
	dlg_t* dialog_info = NULL;
	str met = {"REFER", 5};
	int result;
	str hdrs;
	struct dlg_cell *dlg;
	uac_req_t uac_r;

	dlg = dtc->dlg;

	if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto error;
	}

	hdrs.len = 23 + 2*CRLF_LEN + dlg_bridge_controller.len
		+ dtc->to.len + dlg_bridge_ref_hdrs.len;
	LM_DBG("sending REFER [%d] <%.*s>\n", hdrs.len, dtc->to.len, dtc->to.s);
	hdrs.s = (char*)pkg_malloc(hdrs.len*sizeof(char));
	if(hdrs.s == NULL)
		goto error;
	memcpy(hdrs.s, "Referred-By: ", 13);
	memcpy(hdrs.s+13, dlg_bridge_controller.s, dlg_bridge_controller.len);
	memcpy(hdrs.s+13+dlg_bridge_controller.len, CRLF, CRLF_LEN);
	memcpy(hdrs.s+13+dlg_bridge_controller.len+CRLF_LEN, "Refer-To: ", 10);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN, dtc->to.s,
			dtc->to.len);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len,
			CRLF, CRLF_LEN);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len+CRLF_LEN,
			dlg_bridge_ref_hdrs.s, dlg_bridge_ref_hdrs.len);

	set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
				dlg_refer_tm_callback, (void*)dtc);
	result = d_tmb.t_request_within(&uac_r);

	pkg_free(hdrs.s);
	if(result < 0) {
		LM_ERR("failed to send the REFER request\n");
		/* todo: clean-up dtc */
		goto error;
	}

	free_tm_dlg(dialog_info);

	LM_DBG("REFER sent\n");
	return 0;

error:
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return -1;
}
Ejemplo n.º 8
0
static int prepare_winfo_notify(struct retr_buf **dst,
                                struct presentity* _p, struct watcher* _w,
                                pa_notify_cb_param_t *cbd)
{
    str doc = STR_NULL;
    str content_type = STR_NULL;
    str headers = STR_NULL;
    int res = 0;
    str body = STR_STATIC_INIT("");
    uac_req_t	uac_r;

    switch (_w->preferred_mimetype) {
    case DOC_WINFO:
        create_winfo_document(_p, _w, &doc, &content_type);
        DEBUG("winfo document created\n");
        break;
    /* other formats ? */
    default:
        ERR("unknow doctype\n");
        return -1;
    }

    if (create_headers(_w, &headers, &content_type) < 0) {
        ERR("Error while adding headers\n");
        str_free_content(&doc);
        str_free_content(&content_type);
        return -7;
    }

    if (!is_str_empty(&doc)) body = doc;
    /* res = tmb.t_request_within(&notify, &headers, &body, _w->dialog, 0, 0); */
    set_uac_req(&uac_r,
                &notify,
                &headers,
                &body,
                _w->dialog,
                TMCB_LOCAL_COMPLETED,
                pa_notify_cb,
                cbd
               );
    res = tmb.prepare_request_within(&uac_r, dst);
    if (res < 0) {
        ERR("Can't send watcherinfo notification (%d)\n", res);
    }
    else {
        _w->document_index++; /* increment index for next document */
    }

    str_free_content(&doc);
    str_free_content(&headers);
    str_free_content(&content_type);

    return res;
}
Ejemplo n.º 9
0
void dlg_refer_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
{
	dlg_transfer_ctx_t *dtc = NULL;
	dlg_t* dialog_info = NULL;
	str met = {"BYE", 3};
	int result;
	struct dlg_cell *dlg;
	uac_req_t uac_r;

	if(ps->param==NULL || *ps->param==0)
	{
		LM_DBG("message id not received\n");
		return;
	}
	dtc = *((dlg_transfer_ctx_t**)ps->param);
	if(dtc==NULL)
		return;
	LM_DBG("REFER completed with status %d\n", ps->code);

	/* we send the BYE anyhow */
	dlg = dtc->dlg;
	if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto error;
	}

	/* after REFER, the CSeq must be increased */
	dialog_info->loc_seq.value++;

	set_uac_req(&uac_r, &met, NULL, NULL, dialog_info, 0, NULL, NULL);
	result = d_tmb.t_request_within(&uac_r);

	if(result < 0) {
		LM_ERR("failed to send the REFER request\n");
		/* todo: clean-up dtc */
		goto error;
	}

	free_tm_dlg(dialog_info);
	dlg_transfer_ctx_free(dtc);

	LM_DBG("BYE sent\n");
	return;

error:
	dlg_transfer_ctx_free(dtc);
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return;

}
Ejemplo n.º 10
0
/* cell- pointer to a struct dlg_cell
 * dir- direction: the request will be sent to:
 * 		DLG_CALLER_LEG (0): caller
 * 		DLG_CALLEE_LEG (1): callee
 */
static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
{
	uac_req_t uac_r;
	dlg_t* dialog_info;
	str met = {"BYE", 3};
	int result;
	dlg_iuid_t *iuid = NULL;

	/* do not send BYE request for non-confirmed dialogs (not supported) */
	if (cell->state != DLG_STATE_CONFIRMED_NA && cell->state != DLG_STATE_CONFIRMED) {
		LM_ERR("terminating non-confirmed dialogs not supported\n");
		return -1;
	}

	/*verify direction*/

	if ((dialog_info = build_dlg_t(cell, dir)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto err;
	}

	LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");

	iuid = dlg_get_iuid_shm_clone(cell);
	if(iuid==NULL)
	{
		LM_ERR("failed to create dialog unique id clone\n");
		goto err;
	}

	memset(&uac_r,'\0', sizeof(uac_req_t));
	set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
				bye_reply_cb, (void*)iuid);
	result = d_tmb.t_request_within(&uac_r);

	if(result < 0){
		LM_ERR("failed to send the BYE request\n");
		goto err;
	}

	free_tm_dlg(dialog_info);

	LM_DBG("BYE sent to %s\n", (dir==0)?"caller":"callee");
	return 0;

err:
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return -1;
}
Ejemplo n.º 11
0
int send_winfo_notify_offline(struct presentity* _p,
                              struct watcher* _w,
                              offline_winfo_t *info,
                              transaction_cb completion_cb, void* cbp)
{
    str doc = STR_NULL;
    str content_type = STR_NULL;
    str headers = STR_NULL;
    str body = STR_STATIC_INIT("");
    uac_req_t	uac_r;

    switch (_w->preferred_mimetype) {
    case DOC_WINFO:
        create_winfo_document_offline(_p, _w, info, &doc, &content_type);
        break;
    /* other formats ? */
    default:
        ERR("send_winfo_notify: unknow doctype\n");
        return -1;
    }

    if (create_headers(_w, &headers, &content_type) < 0) {
        ERR("send_winfo_notify(): Error while adding headers\n");
        str_free_content(&doc);
        str_free_content(&content_type);
        return -7;
    }

    if (!is_str_empty(&doc)) body = doc;
    set_uac_req(&uac_r,
                &notify,
                &headers,
                &body,
                _w->dialog,
                TMCB_LOCAL_COMPLETED,
                completion_cb,
                cbp
               );
    tmb.t_request_within(&uac_r);

    str_free_content(&doc);
    str_free_content(&headers);
    str_free_content(&content_type);

    _w->document_index++; /* increment index for next document */

    if (use_db) db_update_watcher(_p, _w); /* dialog and index have changed */

    return 0;
}
Ejemplo n.º 12
0
int imc_send_message(str *src, str *dst, str *headers, str *body)
{
	uac_req_t uac_r;
	if(src==NULL || dst==NULL || body==NULL)
		return -1;
	/* to-do: callbac to remove user fi delivery fails */
	set_uac_req(&uac_r, &imc_msg_type, headers, body, 0, 0, 0, 0);
	tmb.t_request(&uac_r,
			NULL,										/* Request-URI */
			dst,										/* To */
			src,										/* From */
			(outbound_proxy.s)?&outbound_proxy:NULL  	/* outbound proxy */
		);
	return 0;
}
Ejemplo n.º 13
0
int imc_handle_help(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst)
{
	str body;
	uac_req_t uac_r;

	body.s   = IMC_HELP_MSG;
	body.len = IMC_HELP_MSG_LEN;

	LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s);
	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, 0, 0, 0);
	tmb.t_request(&uac_r,
				NULL,									/* Request-URI */
				src,									/* To */
				dst,									/* From */
				(outbound_proxy.s)?&outbound_proxy:NULL/* outbound proxy */
				);
	return 0;
}
Ejemplo n.º 14
0
static int sca_notify_subscriber_internal(sca_mod *scam, sca_subscription *sub,
		str *headers)
{
	uac_req_t request;
	dlg_t *dlg = NULL;
	str state_str = STR_NULL;
	int rc = -1;

	sca_appearance_state_to_str(sub->state, &state_str);
	LM_DBG("SCA: NOTIFYing subscriber '%.*s' of event '%s' with a state of '%.*s' to index '%d'\n",
			STR_FMT(&sub->subscriber), sca_event_name_from_type(sub->event),
			STR_FMT(&state_str), sub->index);

	dlg = sca_notify_dlg_for_subscription(sub);
	if (dlg == NULL) {
		LM_ERR("Failed to create dlg_t for %s NOTIFY to %.*s\n",
				sca_event_name_from_type(sub->event),
				STR_FMT(&sub->subscriber));
		goto done;
	}

	set_uac_req(&request, (str *)&SCA_METHOD_NOTIFY, headers, NULL, dlg,
			TMCB_LOCAL_COMPLETED, sca_notify_reply_cb, scam);
	rc = scam->tm_api->t_request_within(&request);
	if (rc < 0) {
		LM_ERR("Failed to send in-dialog %s NOTIFY to %.*s\n",
				sca_event_name_from_type(sub->event),
				STR_FMT(&sub->subscriber));
	}
	// fall through, return rc from t_request_within

	done: if (dlg != NULL) {
		if (dlg->route_set != NULL) {
			free_rr(&dlg->route_set);
		}

		pkg_free(dlg);
	}

	return (rc);
}
Ejemplo n.º 15
0
int prepare_unauthorized_notify(struct retr_buf **dst,
                                struct presentity* _p, struct watcher* _w,
                                pa_notify_cb_param_t *cbd)
{
    str headers = STR_NULL;
    str body = STR_STATIC_INIT("");
    int res;
    unc_req_t	uac_r;

    /* send notifications to unauthorized (pending) watchers */
    if (create_headers(_w, &headers, NULL) < 0) {
        LOG(L_ERR, "notify_unauthorized_watcher(): Error while adding headers\n");
        return -7;
    }

    set_uac_req(&uac_r,
                &notify,
                &headers,
                &body,
                _w->dialog,
                TMCB_LOCAL_COMPLETED,
                pa_notify_cb,
                cbd
               );
    res = tmb.prepare_request_within(&uac_r, dst);
    if (res < 0) {
        ERR("Can't send NOTIFY (%d) in dlg %.*s, %.*s, %.*s\n", res,
            FMT_STR(_w->dialog->id.call_id),
            FMT_STR(_w->dialog->id.rem_tag),
            FMT_STR(_w->dialog->id.loc_tag));
    }

    str_free_content(&headers);


    return res;
}
Ejemplo n.º 16
0
/**
 * Creates a NOTIFY message and sends it
 * @param n - the r_notification to create the NOTIFY after
 */
void send_notification(r_notification *n)
{
	str h={0,0};
	int k=0;
#ifdef SER_MOD_INTERFACE
        uac_req_t req;
#endif
        
	LOG(L_DBG,"DBG:"M_NAME":send_notification: NOTIFY about <%.*s>\n",n->uri.len,n->uri.s);
	
	//tmb.print_dlg(stdout,n->dialog);
	
	h.len = 0;
	h.len += contact_hdr1.len + n->uri.len + contact_hdr2.len ;
	if (n->subscription_state.len) h.len += subss_hdr1.len + subss_hdr2.len + n->subscription_state.len;
	h.len+=event_hdr.len;
	h.len+=maxfwds_hdr.len;
	if (n->content_type.len) h.len += ctype_hdr1.len + ctype_hdr2.len + n->content_type.len;
	h.s = pkg_malloc(h.len);
	if (!h.s){
		LOG(L_ERR,"ERR:"M_NAME":send_notification: Error allocating %d bytes\n",h.len);
		h.len = 0;
	}

	h.len = 0;
	STR_APPEND(h,contact_hdr1);
	STR_APPEND(h,n->uri);
	STR_APPEND(h,contact_hdr2);

	STR_APPEND(h,event_hdr);
	STR_APPEND(h,maxfwds_hdr);
	if (n->subscription_state.len) {
		STR_APPEND(h,subss_hdr1);
		STR_APPEND(h,n->subscription_state);
		STR_APPEND(h,subss_hdr2);
	}
	if (n->content_type.len) {
		STR_APPEND(h,ctype_hdr1);
		STR_APPEND(h,n->content_type);
		STR_APPEND(h,ctype_hdr2);
	}
	
	//LOG(L_CRIT,"DLG:%p\n",n->dialog);
	#ifdef WITH_IMS_PM
		k = n->is_scscf_dereg;
	#endif 
	if (n->content.len)	{
#ifdef SER_MOD_INTERFACE
		set_uac_req(&req,
					&method,
					&h,
					&(n->content),
					n->dialog,
					TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED,
					uac_request_cb,
					(void*)k);
		tmb.t_request_within(&req);
#else	
		tmb.t_request_within(&method, &h, &(n->content), n->dialog, uac_request_cb, (void*)k);
#endif		
	} else { 
#ifdef SER_MOD_INTERFACE
		set_uac_req(&req,
					&method,
					0,
					&(n->content),
					n->dialog,
					TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED,
					uac_request_cb,
					(void*)k);
		tmb.t_request_within(&req);
#else	
		tmb.t_request_within(&method, &h, 0, n->dialog, uac_request_cb, (void*)k);
#endif		
	}
	if (h.s) pkg_free(h.s);
	
	#ifdef WITH_IMS_PM
		if (n->is_scscf_dereg) IMS_PM_LOG11(UR_AttDeRegCscf,n->dialog->id.call_id,n->dialog->loc_seq.value);
	#endif 
}
Ejemplo n.º 17
0
int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
		struct sip_uri *src, struct sip_uri *dst)
{
	imc_room_p room = 0;
	imc_member_p member = 0;
	int flag_member = 0;
	int size = 0;
	int i = 0;
	int add_domain = 0;
	int add_sip = 0;
	str uri = {0, 0};
	str body;
	str room_name;
	struct sip_uri inv_uri;
	del_member_t *cback_param = NULL;
	int result;
	uac_req_t uac_r;

	size = cmd->param[0].len+2 ;	
	add_domain = 1;
	add_sip = 0;
	while (i<size )
	{
		if(cmd->param[0].s[i]== '@')
		{	
			add_domain = 0;
			break;
		}
		i++;
	}

	if(add_domain)
		size += dst->host.len;
	if(cmd->param[0].len<4 || strncmp(cmd->param[0].s, "sip:", 4)!=0)
	{
		size += 4;
		add_sip = 1;
	}
		
	uri.s = (char*)pkg_malloc(size *sizeof(char));
	if(uri.s == NULL)
	{
		LM_ERR("no more pkg memory\n");
		goto error;
	}
	size= 0;
	if(add_sip)
	{	
		strcpy(uri.s, "sip:");
		size=4;
	}
		
	memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len);
	size += cmd->param[0].len;

	if(add_domain)
	{	
		uri.s[size] = '@';
		size++;
		memcpy(uri.s+ size, dst->host.s, dst->host.len);
		size+= dst->host.len;
	}
	uri.len = size;

	if(parse_uri(uri.s, uri.len, &inv_uri)!=0)
	{
		LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s);
		goto error;
	}
					
	room_name = (cmd->param[1].s)?cmd->param[1]:dst->user;
	room = imc_get_room(&room_name, &dst->host);				
	if(room== NULL || (room->flags&IMC_ROOM_DELETED))
	{
		LM_ERR("the room does not exist [%.*s]!\n",
				room_name.len, room_name.s);
		goto error;
	}			
	member= imc_get_member(room, &src->user, &src->host);

	if(member==NULL)
	{
		LM_ERR("user [%.*s] is not member of[%.*s]!\n",
			src->user.len, src->user.s, room_name.len, room_name.s);
		goto error;
	}
	if(!(member->flags & IMC_MEMBER_OWNER) &&
			!(member->flags & IMC_MEMBER_ADMIN))
	{
		LM_ERR("user [%.*s] has no right to invite"
				" other users!\n", src->user.len, src->user.s);
		goto error;
	}
    
	member= imc_get_member(room, &inv_uri.user, &inv_uri.host);
	if(member!=NULL)
	{
		LM_ERR("user [%.*s] is already member"
				" of the room!\n", inv_uri.user.len, inv_uri.user.s);
		goto error;
	}
		
	flag_member |= IMC_MEMBER_INVITED;		
	member=imc_add_member(room, &inv_uri.user, &inv_uri.host, flag_member);
	if(member == NULL)
	{
		LM_ERR("adding member [%.*s]\n",
				inv_uri.user.len, inv_uri.user.s);
		goto error;	
	}
	
	body.len = 13 + member->uri.len - 4/* sip: */ + 28;	
	if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE
			|| room->uri.len>=IMC_BUF_SIZE)
	{
		LM_ERR("buffer size overflow\n");
		goto error;	
	}

	body.s = imc_body_buf;
	memcpy(body.s, "INVITE from: ", 13);
	memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4);
	memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28);	
	body.s[body.len] = '\0';			

	LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n", 
			member->uri.len,member->uri.s,room->uri.len, room->uri.s,
			body.len, body.s);
				
	cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t));
	if(cback_param==NULL)
	{
		LM_ERR("no more shm\n");
		goto error;	
	}
	memset(cback_param, 0, sizeof(del_member_t));
	cback_param->room_name = room->name;
	cback_param->room_domain = room->domain;
	cback_param->member_name = member->user;
	cback_param->member_domain = member->domain;
	cback_param->inv_uri = member->uri;
	/*?!?! possible race with 'remove user' */

	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, TMCB_LOCAL_COMPLETED,
				imc_inv_callback, (void*)(cback_param));
	result= tmb.t_request(&uac_r,
				&member->uri,							/* Request-URI */
				&member->uri,							/* To */
				&room->uri,								/* From */
				(outbound_proxy.s)?&outbound_proxy:NULL/* outbound proxy*/
			);				
	if(result< 0)
	{
		LM_ERR("in tm send request\n");
		shm_free(cback_param);
		goto error;
	}
	if(uri.s!=NULL)
		pkg_free(uri.s);

	imc_release_room(room);

	return 0;

error:
	if(uri.s!=0)
		pkg_free(uri.s);
	if(room!=NULL)
		imc_release_room(room);
	return -1;
}
Ejemplo n.º 18
0
void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps)
{
	str body_final;
	char from_uri_buf[256];
	char to_uri_buf[256];
	char body_buf[256];
	str from_uri_s, to_uri_s;
	imc_member_p member= NULL;
	imc_room_p room = NULL;
	uac_req_t uac_r;

	if(ps->param==NULL || *ps->param==NULL || 
			(del_member_t*)(*ps->param) == NULL)
	{
		LM_DBG("member not received\n");
		return;
	}
	
	LM_DBG("completed with status %d [member name domain:"
			"%p/%.*s/%.*s]\n",ps->code, ps->param, 
			((del_member_t *)(*ps->param))->member_name.len,
			((del_member_t *)(*ps->param))->member_name.s,
			((del_member_t *)(*ps->param))->member_domain.len, 
			((del_member_t *)(*ps->param))->member_domain.s);
	if(ps->code < 300)
		return;
	else
	{
		room= imc_get_room(&((del_member_t *)(*ps->param))->room_name,
						&((del_member_t *)(*ps->param))->room_domain );
		if(room==NULL)
		{
			LM_ERR("the room does not exist!\n");
			goto error;
		}			
		/*verify if the user who sent the request is a member in the room
		 * and has the right to remove other users */
		member= imc_get_member(room,
				&((del_member_t *)(*ps->param))->member_name,
				&((del_member_t *)(*ps->param))->member_domain);

		if(member== NULL)
		{
			LM_ERR("the user is not a member of the room!\n");
			goto error;
		}
		imc_del_member(room,
				&((del_member_t *)(*ps->param))->member_name,
				&((del_member_t *)(*ps->param))->member_domain);
		goto build_inform;

	}
	

build_inform:
		
	body_final.s = body_buf;
	body_final.len = member->uri.len - 4 /* sip: part of URI */ + 20;
	memcpy(body_final.s, member->uri.s + 4, member->uri.len - 4);
	memcpy(body_final.s+member->uri.len-4," is not registered.  ",21);
		
	goto send_message;

send_message:
	
	from_uri_s.s = from_uri_buf;
	from_uri_s.len = room->uri.len;
	strncpy(from_uri_s.s, room->uri.s, room->uri.len);

	LM_DBG("sending message\n");
	
	to_uri_s.s = to_uri_buf;
	to_uri_s.len = ((del_member_t *)(*ps->param))->inv_uri.len;
	strncpy(to_uri_s.s,((del_member_t *)(*ps->param))->inv_uri.s ,
			((del_member_t *)(*ps->param))->inv_uri.len);

	LM_DBG("to: %.*s\nfrom: %.*s\nbody: %.*s\n", to_uri_s.len, to_uri_s.s,
			from_uri_s.len, from_uri_s.s, body_final.len, body_final.s);
	set_uac_req(&uac_r, &imc_msg_type, &extra_hdrs, &body_final, 0, 0, 0, 0);
	tmb.t_request(&uac_r,
					NULL,									/* Request-URI */
					&to_uri_s,								/* To */
					&from_uri_s,							/* From */
					(outbound_proxy.s)?&outbound_proxy:NULL /* outbound proxy*/
				);
	if(room!=NULL)
	{
		imc_release_room(room);
	}

	if((del_member_t *)(*ps->param))
		shm_free(*ps->param);

	return;

error:
	if(room!=NULL)
	{
		imc_release_room(room);
	}
	if((del_member_t *)(*ps->param))
		shm_free(*ps->param);
	return; 
}
Ejemplo n.º 19
0
int r_send_third_party_reg(r_third_party_registration *r, int expires) {
    str h = {0, 0};
    str b = {0, 0};
    uac_req_t req;

    LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n",
	    r->req_uri.len, r->req_uri.s);

    h.len = event_hdr.len + max_fwds_hdr.len;
    h.len += expires_s.len + 12 + expires_e.len;

    h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len;

    if (r->pvni.len) {
        h.len += p_visited_network_id_s.len + p_visited_network_id_e.len
            + r->pvni.len;
    }
    if (r->pani.len) {
        h.len += p_access_network_info_s.len + p_access_network_info_e.len
            + r->pani.len;
    }
    if (r->cv.len) {
        h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len;
    }
    if (r->path.len) {
        h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/
            + r->from.len /*adding our own address to path*/;
    }
	str pauri = {0,0};

	if (p_associated_uri.data_len > 0)
	{
		pauri.s = p_associated_uri.buf;
		pauri.len = p_associated_uri.data_len;
		h.len += pauri.len;
	}

    if (r->body.content_type == CT_SERVICE_INFO) {
        h.len += content_type_s.len;
        h.len += ct_service_info.len;
        h.len += content_type_e.len;
    } else if (r->body.content_type == CT_REGISTER_REQ) {
        h.len += content_type_s.len;
        h.len += ct_register_req.len;
        h.len += content_type_e.len;
    } else if (r->body.content_type == CT_REGISTER_RESP) {
        h.len += content_type_s.len;
        h.len += ct_register_resp.len;
        h.len += content_type_e.len;
    }

    h.s = pkg_malloc(h.len);
    if (!h.s) {
	LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
	h.len = 0;
	return 0;
    }

    h.len = 0;
    STR_APPEND(h, event_hdr);

    STR_APPEND(h, max_fwds_hdr);

    STR_APPEND(h, expires_s);
    sprintf(h.s + h.len, "%d", expires);
    h.len += strlen(h.s + h.len);
    STR_APPEND(h, expires_e);

    if (r->path.len) {
	STR_APPEND(h, path_s);
	STR_APPEND(h, path_mine_s);
	STR_APPEND(h, r->from);
	STR_APPEND(h, path_mine_e);
	STR_APPEND(h, comma);
	STR_APPEND(h, r->path);
	STR_APPEND(h, path_e);
    }

    STR_APPEND(h, contact_s);
    STR_APPEND(h, isc_my_uri_sip);
    STR_APPEND(h, contact_e);

    if (r->pvni.len) {
	STR_APPEND(h, p_visited_network_id_s);
	STR_APPEND(h, r->pvni);
	STR_APPEND(h, p_visited_network_id_e);
    }

    if (r->pani.len) {
	STR_APPEND(h, p_access_network_info_s);
	STR_APPEND(h, r->pani);
	STR_APPEND(h, p_access_network_info_e);
    }

    if (r->cv.len) {
	STR_APPEND(h, p_charging_vector_s);
	STR_APPEND(h, r->cv);
	STR_APPEND(h, p_charging_vector_e);
    }

    if (p_associated_uri.data_len > 0) {
		STR_APPEND(h, pauri);
	}
    LM_DBG("BODY TYPE(3rd PARTY REGISTER):<%d>\n", r->body.content_type);
    if (r->body.content_type != CT_NONE) {
	if (r->body.content_type == CT_SERVICE_INFO) {
		LM_ERR("BODY (3rd PARTY REGISTER) \"SI\": <%.*s>\n", r->body.content.len, r->body.content.s);
		b.len = body_s.len + r->body.content.len + body_e.len;
		b.s = pkg_malloc(b.len);
		if (!b.s) {
		    LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
		    b.len = 0;
		    goto error;
		}
		b.len = 0;
		STR_APPEND(b, body_s);
		STR_APPEND(b, r->body.content);
		STR_APPEND(b, body_e);
		STR_APPEND(h, content_type_s);
		STR_APPEND(h, ct_service_info);
		STR_APPEND(h, content_type_e);
	} else if (r->body.content_type == CT_REGISTER_REQ) {
		LM_ERR("BODY (3rd PARTY REGISTER) \"REQ\": <%.*s>\n", r->body.content.len, r->body.content.s);
		b.len = r->body.content.len;
		b.s = pkg_malloc(b.len);
		if (!b.s) {
                    LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
                    b.len = 0;
                    goto error;
                }
		b.len = 0;
		STR_APPEND(b, r->body.content);
		STR_APPEND(h, content_type_s);
                STR_APPEND(h, ct_register_req);
                STR_APPEND(h, content_type_e);
	} else if (r->body.content_type == CT_REGISTER_RESP) {
		LM_ERR("BODY (3rd PARTY REGISTER) \"RESP\": <%.*s>\n", r->body.content.len, r->body.content.s);
		b.len = r->body.content.len;
                b.s = pkg_malloc(b.len);
                if (!b.s) {
                    LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
                    b.len = 0;
                    goto error;
                }
                b.len = 0;
                STR_APPEND(b, r->body.content);
                STR_APPEND(h, content_type_s);
                STR_APPEND(h, ct_register_resp);
                STR_APPEND(h, content_type_e);
	}
    }

    set_uac_req(&req, &method, &h, &b, 0,
	    TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED,
	    r_third_party_reg_response, &(r->req_uri));
    if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) {
	LM_ERR("r_send_third_party_reg: Error sending in transaction\n");
	goto error;
    }
    if (h.s)
	pkg_free(h.s);
    if (b.s)
	pkg_free(b.s);
    if (r->body.content_type == CT_REGISTER_RESP)
	pkg_free(r->body.content.s);
    return 1;

error:
    if (h.s)
	pkg_free(h.s);
    if (b.s)
	pkg_free(b.s);
    if (r->body.content_type == CT_REGISTER_RESP)
        pkg_free(r->body.content.s);
    return 0;
}
Ejemplo n.º 20
0
/**
 * @brief send a dmq message
 *
 * peer - the peer structure on behalf of which we are sending
 * body - the body of the message
 * node - we send the message to this node
 * resp_cback - a response callback that gets called when the transaction is complete
 */
int dmq_send_message(dmq_peer_t *peer, str *body, dmq_node_t *node,
		dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type)
{
	uac_req_t uac_r;
	str str_hdr = {0, 0};
	str from = {0, 0}, to = {0, 0};
	dmq_cback_param_t *cb_param = NULL;
	int result = 0;
	int len = 0;

	if(!content_type) {
		LM_ERR("content-type is null\n");
		return -1;
	}
	/* add Max-Forwards and Content-Type headers */
	str_hdr.len = 34 + content_type->len + (CRLF_LEN * 2);
	str_hdr.s = pkg_malloc(str_hdr.len);
	if(str_hdr.s == NULL) {
		LM_ERR("no more pkg\n");
		return -1;
	}
	len += sprintf(str_hdr.s, "Max-Forwards: %d" CRLF "Content-Type: %.*s" CRLF,
			max_forwards, content_type->len, content_type->s);
	str_hdr.len = len;

	cb_param = shm_malloc(sizeof(*cb_param));
	if(cb_param == NULL) {
		LM_ERR("no more shm for building callback parameter\n");
		goto error;
	}
	memset(cb_param, 0, sizeof(*cb_param));
	cb_param->resp_cback = *resp_cback;
	cb_param->node = shm_dup_node(node);
	if(cb_param->node == NULL) {
		LM_ERR("error building callback parameter\n");
		goto error;
	}

	if(build_uri_str(&peer->peer_id, &dmq_server_uri, &from) < 0) {
		LM_ERR("error building from string [username %.*s]\n",
				STR_FMT(&peer->peer_id));
		goto error;
	}
	if(build_uri_str(&peer->peer_id, &node->uri, &to) < 0) {
		LM_ERR("error building to string\n");
		goto error;
	}

	set_uac_req(&uac_r, &dmq_request_method, &str_hdr, body, NULL,
			TMCB_LOCAL_COMPLETED, dmq_tm_callback, (void *)cb_param);
	uac_r.ssock = &dmq_server_socket;

	result = tmb.t_request(&uac_r, &to, &to, &from, NULL);
	if(result < 0) {
		LM_ERR("error in tmb.t_request_within\n");
		goto error;
	}
	pkg_free(str_hdr.s);
	pkg_free(from.s);
	pkg_free(to.s);
	return 0;
error:
	pkg_free(str_hdr.s);
	if(from.s != NULL)
		pkg_free(from.s);
	if(to.s != NULL)
		pkg_free(to.s);
	if(cb_param) {
		if(cb_param->node)
			destroy_dmq_node(cb_param->node, 1);
		shm_free(cb_param);
	}
	return -1;
}
Ejemplo n.º 21
0
Archivo: pua.c Proyecto: kiryu/kamailio
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;

}
Ejemplo n.º 22
0
static int prepare_presence_notify(struct retr_buf **dst,
                                   struct presentity* _p, struct watcher* _w,
                                   pa_notify_cb_param_t *cbd)
{
    /* Send a notify, saved Contact will be put in
     * Request-URI, To will be put in from and new tag
     * will be generated, callid will be callid,
     * from will be put in to including tag
     */
    str doc = STR_NULL;
    str content_type = STR_NULL;
    str headers = STR_NULL;
    str body = STR_STATIC_INIT("");
    int res = 0;
    uac_req_t	uac_r;

    switch(_w->preferred_mimetype) {
    case DOC_XPIDF:
        res = create_xpidf_document(&_p->data, &doc, &content_type);
        break;

    case DOC_LPIDF:
        res = create_lpidf_document(&_p->data, &doc, &content_type);
        break;

    case DOC_CPIM_PIDF:
        res = create_cpim_pidf_document(&_p->data, &doc, &content_type);
        break;

    case DOC_MSRTC_PIDF:
    case DOC_PIDF:
    default:
        res = create_pidf_document(&_p->data, &doc, &content_type);
    }

    if (res != 0) {
        LOG(L_ERR, "can't create presence document (%d)\n", _w->preferred_mimetype);
        return -2;
    }

    if (create_headers(_w, &headers, &content_type) < 0) {
        LOG(L_ERR, "send_presence_notify(): Error while adding headers\n");
        str_free_content(&doc);
        str_free_content(&content_type);

        return -7;
    }

    if (!is_str_empty(&doc)) body = doc;
    /*	res = tmb.t_request_within(&notify, &headers, &body,
    			_w->dialog, pa_notify_cb, cbd);*/
    set_uac_req(&uac_r,
                &notify,
                &headers,
                &body,
                _w->dialog,
                TMCB_LOCAL_COMPLETED,
                pa_notify_cb,
                cbd
               );
    res = tmb.prepare_request_within(&uac_r, dst);
    if (res < 0) {
        ERR("Can't send NOTIFY (%d) in dlg %.*s, %.*s, %.*s\n", res,
            FMT_STR(_w->dialog->id.call_id),
            FMT_STR(_w->dialog->id.rem_tag),
            FMT_STR(_w->dialog->id.loc_tag));
    }

    str_free_content(&doc);
    str_free_content(&headers);
    str_free_content(&content_type);

    return res;
}
Ejemplo n.º 23
0
/*Actions are composed as follows:
 * (the action length and type as always= 5 bytes)
 * 4:uac_id
 *
 * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp)
 * TODO performance speedup: instead of using
 * dynamically allocated memory for headers,body,totag,reason and my_msg
 * use static buffers.
 *
 */
int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len)
{
   unsigned int cseq;
   char err_buf[MAX_REASON_LEN];
   struct sip_msg *my_msg;
   struct to_body *fb,*tb;
   struct cseq_body *cseqb;
   struct as_uac_param *the_param;
   dlg_t *my_dlg;
   int k,retval,uac_id,sip_error,ret,err_ret;
   long clen;
   str headers,body,fake_uri;
   uac_req_t uac_r;

   headers.s=body.s=fake_uri.s=NULL;
   my_dlg=NULL;
   my_msg=NULL;
   the_param=NULL;
   k=clen=0;

   net2hostL(uac_id,action,k);

   if(!(headers.s=pkg_malloc(MAX_HEADER))){
      LM_ERR("Out of Memory!!");
      goto error;
   }
   headers.len=0;
   LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id);
   if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) {
      LM_ERR("out of memory!\n");
      goto error;
   }
   if(my_msg->first_line.type==SIP_REPLY){
      LM_ERR("trying to create a UAC with a SIP response!!\n");
      goto error;
   }
   if(parse_headers(my_msg,HDR_EOH_F,0)==-1){
      LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n");
      goto error;
   }
   if(parse_from_header(my_msg)<0){
      LM_ERR("parsing from header ! \n");
      goto error;
   }
   if(check_transaction_quadruple(my_msg)==0){
      as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0);
      LM_ERR("Headers missing (to,from,call-id,cseq)?");
      goto error;
   }
   if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) || 
	 !(get_from(my_msg)->tag_value.len)){
      as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0);
      LM_ERR("From tag missing");
      goto error;
   }
   fb=my_msg->from->parsed;
   tb=my_msg->to->parsed;
   cseqb=my_msg->cseq->parsed;
   if(0!=(str2int(&cseqb->number,&cseq))){
      LM_DBG("unable to parse CSeq\n");
      goto error;
   }
   if(my_msg->first_line.u.request.method_value != METHOD_ACK &&
	 my_msg->first_line.u.request.method_value != METHOD_CANCEL) {
      /** we trick req_within */
      cseq--;
   }
   if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\
	    &(fb->uri),&(tb->uri),&my_dlg) < 0) {
      as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0);
      LM_ERR("Error while creating new dialog\n");
      goto error;
   }
   if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) {
      as_action_fail_resp(uac_id,SE_UAC,
         "Error adding the display names to the new dialog",0);
      LM_ERR("failed to add display names to the new dialog\n");
      goto error;
   }

   if(tb->tag_value.s && tb->tag_value.len)
      shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value);
   /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have
    * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID
    * and ftag), so we have to simulate that the dialog is already in completed
    * state so...
    */
   server_signature=0;
   my_dlg->state = DLG_CONFIRMED;
   if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) {
      LM_ERR("Unable to extract allowed headers!!\n");
      goto error;
   }
   headers.s[headers.len]=0;
   /*let's get the body*/
   if(my_msg->content_length)
      clen=(long)get_content_length(my_msg);
   if(clen!=0){
      if(!(body.s=pkg_malloc(clen))){
	 LM_ERR("Out of Memory!");
	 goto error;
      }
      memcpy(body.s,get_body(my_msg),clen);
      body.len=clen;
      body.s[clen]=0;
      LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\
	    body.len,body.len,body.s,headers.len,headers.len,headers.s);
      /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/
   }else{
      body.s=NULL;
      body.len=0;
   }
   /*Now... create the UAC !!
    * it would be great to know the hash_index and the label that have been assigned
    * to our newly created cell, but t_uac does not leave any way for us to know...
    * only that when that transaction transitions its state (ie. a response is received,
    * a timeout is reached, etc...) the callback will be called with the given parameter.
    *
    * So the only way we have to know who we are, is passing as a parameter a structure with
    * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id).
    *
    */
   if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){
      LM_ERR("out of shared memory\n");
      goto error;
   }
   the_param->who=my_as;
   the_param->uac_id=uac_id;
   the_param->processor_id=processor_id;
   the_param->destroy_cb_set=0;

   shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri);

   if (my_msg->route) {
      if (parse_rr(my_msg->route) < 0) {
	 LM_ERR( "Error while parsing Route body\n");
	 goto error;
      }
      /* TODO route_set should be a shm copy of my_msg->route->parsed */
      my_dlg->route_set=(rr_t*)my_msg->route->parsed;
      /** this SHOULD be:
       shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed);
       * but it will last more...
       */
   }
   calculate_hooks(my_dlg);
   if(flags & SPIRAL_FLAG){
      memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN);
      headers.len+=SPIRAL_HDR_LEN+CRLF_LEN;
      headers.s[headers.len]=0;
      fake_uri.s=pkg_malloc(200);
      fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200);

      if(fake_uri.len<0){
	 LM_ERR("printing local uri\n");
	 goto error;
      }
      my_dlg->hooks.next_hop=&fake_uri;
   }
   /* Kamailio and OpenSIPs seem to have diverged quite a bit on flags and events
      notified to UACs. Let's see if kamailio gets it right by now, if not
      this is a TODO: check PASS_PROVISIONAL
      my_dlg->T_flags=T_NO_AUTO_ACK|T_PASS_PROVISIONAL_FLAG ;
      this is the same as (TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT) in Kamailio
   */

   set_uac_req(&uac_r, &(my_msg->first_line.u.request.method), &headers,
		   &body, my_dlg,TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT, uac_cb,
		   (void*)the_param);

   ret=seas_f.tmb.t_request_within(&uac_r);

   /** now undo all the fakes we have put in my_dlg*/
   /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/
   my_dlg->route_set=(rr_t *)0;
   if (ret < 0) {
      err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC");
      LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s);
      LM_ERR("Error on request_within %s\n",err_buf );
      if(err_ret > 0) {
	 as_action_fail_resp(uac_id,ret,err_buf,0);
      }else{
	 as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0);
      }
      goto error;
   }
   retval=0;
   goto exit;
error:
   retval = -1;
   if(the_param)
      shm_free(the_param);
exit:
   seas_f.tmb.free_dlg(my_dlg);
   if(headers.s)
      pkg_free(headers.s);
   if(body.s)
      pkg_free(body.s);
   if(fake_uri.s)
      pkg_free(fake_uri.s);
   if(my_msg){
      if(my_msg->headers)
	 free_hdr_field_lst(my_msg->headers);
      pkg_free(my_msg);
   }
   return retval;
}
Ejemplo n.º 24
0
int send_sip_msg_request(str *to, str *from_user, str *body)
{
	str msg_type = STR_STATIC_INIT("MESSAGE");
	str from;
	str hdrs;
	int foo;
	char *p;
	uac_req_t uac_r;

	from.s = hdrs.s = 0;
	from.len = hdrs.len = 0;

	/* From header */
	from.len = 6 /*"<sip:+"*/ +  from_user->len/*user*/ + 1/*"@"*/
		+ domain.len /*host*/ + 1 /*">"*/ ;
	from.s = (char*)pkg_malloc(from.len);
	if (!from.s)
		goto error;
	p=from.s;
	append_str(p,"<sip:+",6);
	append_str(p,from_user->s,from_user->len);
	*(p++)='@';
	append_str(p,domain.s,domain.len);
	*(p++)='>';

	/* hdrs = Contact header + Content-type */
	/* length */
	hdrs.len = CONTENT_TYPE_HDR_LEN + CRLF_LEN;
	if (use_contact)
		hdrs.len += 15 /*"Contact: <sip:+"*/ + from_user->len/*user*/ +
			1/*"@"*/ + domain.len/*host*/ + 1 /*">"*/ + CRLF_LEN;
	hdrs.s = (char*)pkg_malloc(hdrs.len);
	if (!hdrs.s)
		goto error;
	p=hdrs.s;
	append_str(p,CONTENT_TYPE_HDR,CONTENT_TYPE_HDR_LEN);
	append_str(p,CRLF,CRLF_LEN);
	if (use_contact) {
		append_str(p,"Contact: <sip:+",15);
		append_str(p,from_user->s,from_user->len);
		*(p++)='@';
		append_str(p,domain.s,domain.len);
		append_str(p,">"CRLF,1+CRLF_LEN);
	}

	/* sending the request */
	set_uac_req(&uac_r,
			&msg_type,	/* request type */
			&hdrs,		/* Additional headers including CRLF */
			body,		/* Message body */
			0,		/* dialog structure */
			0,		/* callback flags */
			0,		/* Callback function */
			0		/* Callback parameter */
		);
	
	foo = tmb.t_request(&uac_r,
			0,	/* Request-URI */
			to,	/* To */
			&from,	/* From */
			0	/* next hop */
		);

	if (from.s) pkg_free(from.s);
	if (hdrs.s) pkg_free(hdrs.s);
	return foo;
error:
	LM_ERR("no free pkg memory!\n");
	if (from.s) pkg_free(from.s);
	if (hdrs.s) pkg_free(hdrs.s);
	return -1;
}
Ejemplo n.º 25
0
int r_send_third_party_reg(r_third_party_registration *r, int expires) {
    str h = {0, 0};
    str b = {0, 0};
    uac_req_t req;

    LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n",
	    r->req_uri.len, r->req_uri.s);

    h.len = event_hdr.len + max_fwds_hdr.len;
    h.len += expires_s.len + 12 + expires_e.len;

    h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len;

    if (r->pvni.len)
	h.len += p_visited_network_id_s.len + p_visited_network_id_e.len
	    + r->pvni.len;

    if (r->pani.len)
	h.len += p_access_network_info_s.len + p_access_network_info_e.len
	    + r->pani.len;

    if (r->cv.len)
	h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len;

    if (r->path.len)
	h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/;

    h.s = pkg_malloc(h.len);
    if (!h.s) {
	LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
	h.len = 0;
	return 0;
    }

    h.len = 0;
    STR_APPEND(h, event_hdr);

    STR_APPEND(h, max_fwds_hdr);

    STR_APPEND(h, expires_s);
    sprintf(h.s + h.len, "%d", expires);
    h.len += strlen(h.s + h.len);
    STR_APPEND(h, expires_e);

    if (r->path.len) {
	STR_APPEND(h, path_s);
	STR_APPEND(h, path_mine_s);
	STR_APPEND(h, r->from);
	STR_APPEND(h, path_mine_e);
	STR_APPEND(h, comma);
	STR_APPEND(h, r->path);
	STR_APPEND(h, path_e);
    }

    STR_APPEND(h, contact_s);
    STR_APPEND(h, isc_my_uri_sip);
    STR_APPEND(h, contact_e);

    if (r->pvni.len) {
	STR_APPEND(h, p_visited_network_id_s);
	STR_APPEND(h, r->pvni);
	STR_APPEND(h, p_visited_network_id_e);
    }

    if (r->pani.len) {
	STR_APPEND(h, p_access_network_info_s);
	STR_APPEND(h, r->pani);
	STR_APPEND(h, p_access_network_info_e);
    }

    if (r->cv.len) {
	STR_APPEND(h, p_charging_vector_s);
	STR_APPEND(h, r->cv);
	STR_APPEND(h, p_charging_vector_e);
    }
    LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
    if (r->service_info.len) {
	b.len = body_s.len + r->service_info.len + body_e.len;
	b.s = pkg_malloc(b.len);
	if (!b.s) {
	    LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
	    b.len = 0;
	    return 0;
	}

	b.len = 0;
	STR_APPEND(b, body_s);
	STR_APPEND(b, r->service_info);
	STR_APPEND(b, body_e);
    }

    set_uac_req(&req, &method, &h, &b, 0,
	    TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED,
	    r_third_party_reg_response, &(r->req_uri));
    if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) {
	LM_ERR("r_send_third_party_reg: Error sending in transaction\n");
	goto error;
    }
    if (h.s)
	pkg_free(h.s);
    return 1;

error:
    if (h.s)
	pkg_free(h.s);
    return 0;
}
Ejemplo n.º 26
0
int send_subscribe(subs_info_t* subs)
{
	ua_pres_t* presentity= NULL;
	str met= {"SUBSCRIBE", 9};
	str* str_hdr= NULL;
	int ret= -1;
	unsigned int hash_code=0;
	ua_pres_t* hentity= NULL;
	int expires;
	int flag;
	int result;
	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};
	dlg_t* td= NULL;


	memset(&dbpres, 0, sizeof(dbpres));
	dbpres.pres_uri = &pres_uri;
	dbpres.watcher_uri = &watcher_uri;
	dbpres.extra_headers = &extra_headers; 

	print_subs(subs);

	flag= subs->source_flag;
	if(subs->source_flag & XMPP_INITIAL_SUBS)
		subs->source_flag= XMPP_SUBSCRIBE;

	if(subs->expires< 0)
		expires= 3600;
	else
		expires= subs->expires;

	str_hdr= subs_build_hdr(subs->contact, expires, subs->event, 
			subs->extra_headers);
	if(str_hdr== NULL || str_hdr->s== NULL)
	{
		LM_ERR("while building extra headers\n");
		return -1;
	}

	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;
		}
	}

	/* generation of hash and getting lock moved from here to further down */

	if (dbmode==PUA_DB_ONLY)
	{
		presentity = get_dialog_puadb(subs->id, subs->pres_uri, &dbpres, &res);
	}
	else
	{
		ua_pres_t pres;

		memset(&pres, 0, sizeof(ua_pres_t));
		pres.pres_uri = subs->pres_uri;
		pres.watcher_uri = subs->watcher_uri;
		pres.flag = subs->source_flag;
		pres.id = subs->id;
		pres.event = subs->event;
		if (subs->remote_target)
			pres.remote_contact = *subs->remote_target;

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

	/* if flag == INSERT_TYPE insert no matter what the search result is */
	if(subs->flag & INSERT_TYPE)
	{
		LM_DBG("A subscription request with insert type\n");
		goto insert;
	}
	
	if(presentity== NULL )
	{
		int size;
insert:
	
		if (subs->expires == 0)
		{
			/* Don't create a new dialog when expires == 0 */
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		if(subs->flag & UPDATE_TYPE)
		{
			LM_DBG("request for a subscription with update type"
					" and no record found\n");
			subs->flag= INSERT_TYPE;
		}	
		hentity= subscribe_cbparam(subs, REQ_OTHER);
		if(hentity== NULL)
		{
			LM_ERR("while building callback"
					" param\n");
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		hentity->flag= flag;

		set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED,
				subs_cback_func, (void*)hentity);
		result= tmb.t_request_outside
			(&uac_r,						  /* Type of the message */
		subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/
			subs->pres_uri,				  /* To */
			subs->watcher_uri,			  /* From */
			subs->outbound_proxy		  /* Outbound_proxy */	
			);
		if(result< 0)
		{
			LM_ERR("while sending request with t_request\n");
			if (uac_r.dialog != NULL)
			{
				uac_r.dialog->rem_target.s = 0;
				uac_r.dialog->dst_uri.s = 0;
				tmb.free_dlg(uac_r.dialog);
				uac_r.dialog = 0;
			}
			shm_free(hentity);
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);

			/* Although this is an error must not return -1 as the
			   calling function must continue processing. */
			ret = 0;
			goto error;
		}

		/* Now create a temporary hash table entry.
		   This is needed to deal with the race-hazard when NOTIFYs
		   arrive before the 2xx response to the SUBSCRIBE. */
		size = sizeof(ua_pres_t)+ 2 * sizeof(str) + (
			subs->pres_uri->len +
			subs->watcher_uri->len +
			uac_r.dialog->id.loc_tag.len +
			uac_r.dialog->id.call_id.len +
			subs->id.len) * sizeof(char);

		presentity= (ua_pres_t*)shm_malloc(size);
		if(presentity== NULL)
		{
			LM_ERR("no more share memory\n");
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		memset(presentity, 0, size);
		size= sizeof(ua_pres_t);

		presentity->pres_uri = (str *) ((char *) presentity + size);
		size += sizeof(str);
		presentity->pres_uri->s= (char *) presentity + size;
		memcpy(presentity->pres_uri->s, subs->pres_uri->s, subs->pres_uri->len);
		presentity->pres_uri->len= subs->pres_uri->len;
		size+= subs->pres_uri->len;

		presentity->watcher_uri= (str *) ((char *) presentity + size);
		size += sizeof(str);
		presentity->watcher_uri->s= (char *) presentity + size;
		memcpy(presentity->watcher_uri->s, subs->watcher_uri->s, subs->watcher_uri->len);
		presentity->watcher_uri->len = subs->watcher_uri->len;
		size += subs->watcher_uri->len;

		presentity->call_id.s = (char *) presentity + size;
		memcpy(presentity->call_id.s, uac_r.dialog->id.call_id.s, uac_r.dialog->id.call_id.len);
		presentity->call_id.len = uac_r.dialog->id.call_id.len;
		size += uac_r.dialog->id.call_id.len;

		presentity->from_tag.s = (char *) presentity + size;
		memcpy(presentity->from_tag.s, uac_r.dialog->id.loc_tag.s, uac_r.dialog->id.loc_tag.len);
		presentity->from_tag.len= uac_r.dialog->id.loc_tag.len;
		size += uac_r.dialog->id.loc_tag.len;

		presentity->id.s = (char *) presentity+ size;
		memcpy(presentity->id.s, subs->id.s, subs->id.len);
		presentity->id.len = subs->id.len;
		size += subs->id.len;

		presentity->event = subs->event;
		presentity->flag = subs->source_flag;
		presentity->cseq = uac_r.dialog->loc_seq.value;

		/* Set the temporary record expiry for 2 * 64T1 seconds from now */
		presentity->expires= (int)time(NULL) + 64;
		presentity->desired_expires= presentity->expires;

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

		uac_r.dialog->rem_target.s = 0;
		uac_r.dialog->dst_uri.s = 0;
		tmb.free_dlg(uac_r.dialog);
		uac_r.dialog = 0;
	}
	else
	{
		if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE)
		{
			LM_INFO("attempting to re-SUBSCRIBE on internal (rls_update_subs()) update - skipping\n");
			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		if (presentity->to_tag.len == 0)
		{
			if (subs->expires > 0)
				LM_WARN("attempting to re-SUBSCRIBE to a temporary (non-established) dialog - skipping\n");
			else
			{
				LM_WARN("attempting to un-SUBSCRIBE from a temporary (non-established) dialog - skipping and deleting dialog\n");
				if (dbmode==PUA_DB_ONLY)
					delete_dialog_puadb(presentity);
				else
					delete_htable(presentity, hash_code);
			}

			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		td= pua_build_dlg_t(presentity);
		if(td== NULL)
		{
			LM_ERR("while building tm dlg_t structure");
			if (dbmode!=PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
				
		hentity= subs_cbparam_indlg(presentity, expires, REQ_OTHER);
		if(hentity== NULL)
		{
			LM_ERR("while building callback param\n");
			if (dbmode!=PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		if (dbmode!=PUA_DB_ONLY)
			lock_release(&HashT->p_records[hash_code].lock);

		LM_DBG("event parameter: %d\n", hentity->event);	

		set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED,
				subs_cback_func, (void*)hentity);
		result= tmb.t_request_within(&uac_r);
		if(result< 0)
		{
			shm_free(hentity);
			hentity= NULL;
			LM_ERR("while sending request with t_request\n");
			goto error;
		}
	}


done:
	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;
		}
	}

	ret = 0;

error:
	pua_free_tm_dlg(td);
	pkg_free(str_hdr);
	free_results_puadb(res);

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

	return ret;
}
Ejemplo n.º 27
0
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;
}