示例#1
0
文件: notify.c 项目: kiryu/kamailio
static inline int create_headers(struct watcher* _w, str *dst, str *content_type)
{
    dstring_t buf;
    time_t t;
    int err = 0;

    dstr_init(&buf, 256);
    str_clear(dst);

    /* required by RFC 3261 */
    dstr_append_zt(&buf, "Max-Forwards: 70\r\n");

    /* Event header */

    dstr_append_zt(&buf, "Event: ");
    dstr_append_zt(&buf, event_package2str(_w->event_package));
    dstr_append_zt(&buf, "\r\n");

    /* Content-Type header */

    /* content types can have dynamical parameters (multipart/related)
     * => don't generate them "staticaly"; use values created in the
     * time of document creation */
    if (!is_str_empty(content_type)) { /* documents without body doesn't need it */
        dstr_append_zt(&buf, "Content-Type: ");
        dstr_append_str(&buf, content_type);
        dstr_append_zt(&buf, "\r\n");
    }

    /* Contact header */

    if (is_str_empty(&_w->server_contact)) {
        LOG(L_WARN, "add_contact_hf(): Can't add empty contact to NOTIFY.\n");
    }
    else {
        dstr_append_zt(&buf, "Contact: ");
        dstr_append_str(&buf, &_w->server_contact);
        dstr_append_zt(&buf, "\r\n");
    }

    /* Subscription-State header */

    if (_w->expires) t = _w->expires - time(0);
    else t = 0;

    if (add_subs_state_hf(&buf, _w->status, t) < 0) {
        LOG(L_ERR, "create_headers(): Error while adding Subscription-State\n");
        dstr_destroy(&buf);
        return -3;
    }

    err = dstr_get_str(&buf, dst);
    dstr_destroy(&buf);

    return err;
}
示例#2
0
文件: notify.c 项目: kiryu/kamailio
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;
}
示例#3
0
文件: notify.c 项目: kiryu/kamailio
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;
}
示例#4
0
文件: notify.c 项目: kiryu/kamailio
static inline int add_cont_type_hf(dstring_t *buf, str *content_type)
{
    /* content types can have dynamical parameters (multipart/related)
     * => don't generate them "staticaly"; use values created in the
     * time of document creation */

    if (is_str_empty(content_type)) return 0; /* documents without body doesn't need it */

    dstr_append_zt(buf, "Content-Type: ");

    dstr_append_str(buf, content_type);
    dstr_append_zt(buf, "\r\n");

    return 0;
}
示例#5
0
int preset_dialog_route(dlg_t* dialog, str *route)
{
	rr_t *old_r, *r = NULL;
	int res;

	/* check parameters */
	if ((!dialog) || (is_str_empty(route))) {
		ERR("bad parameters\n");
		return -1;
	}
	if (dialog->state != DLG_NEW) {
		ERR("Dialog is not in DLG_NEW state\n");
		return -1;
	}
	
	if (parse_rr_body(route->s, route->len, &r) < 0) {
		ERR("can't parse given route\n");
		return -1;
	}

	if (!r) {
		ERR("empty route\n");
		return -1;
	}

	old_r = dialog->route_set;
	dialog->route_set = NULL;
	res = shm_duplicate_rr(&dialog->route_set, r);
	if (r) free_rr(&r);
	if (res < 0) {
		/* return old routeset to its place */
		dialog->route_set = old_r;
		ERR("can't duplicate route\n");
		return -1;
	}
	
	/* free old route */
	if (old_r) shm_free_rr(&old_r);

	res = tmb.calculate_hooks(dialog);
	if (res < 0) {
		ERR("Error while calculating hooks\n");
		return -2;
	}

	return 0;
}
示例#6
0
static int rls_generate_notify_ext(rl_subscription_t *s, int full_info)
{
	/* !!! the main mutex must be locked here !!! */
	int res;
	str doc;
	dstring_t dstr;
	str headers, content_type;
	static str method = STR_STATIC_INIT(METHOD_NOTIFY);
	dlg_t *dlg;
	int exp_time = 0;
	char expiration[32];
	str body = STR_STATIC_INIT("");
	int removed = 0;

	dlg = s->u.external.dialog;
	if (!dlg) return -1;

	DEBUG("generating external notify\n");
	
	str_clear(&doc);
	str_clear(&content_type);
	if (sm_subscription_pending(&s->u.external) != 0) {
		/* create the document only for non-pending subscriptions */
		if (create_rlmi_document(&doc, &content_type, s, full_info) != 0) {
			return -1;
		}
	}
	
	exp_time = sm_subscription_expires_in(rls_manager, &s->u.external);
	sprintf(expiration, ";expires=%d\r\n", exp_time);
		
	dstr_init(&dstr, 256);
	dstr_append_zt(&dstr, "Subscription-State: ");
	switch (s->u.external.status) {
		case subscription_active: 
				dstr_append_zt(&dstr, "active");
				dstr_append_zt(&dstr, expiration);
				break;
		case subscription_pending: 
				dstr_append_zt(&dstr, "pending");
				dstr_append_zt(&dstr, expiration);
				break;
		case subscription_terminated_pending: 
		case subscription_terminated: 
				dstr_append_zt(&dstr, "terminated\r\n");
				break;
		case subscription_terminated_pending_to: 
		case subscription_terminated_to: 
				dstr_append_zt(&dstr, 
					"terminated;reason=timeout\r\n");
				break;
		case subscription_uninitialized: 
				dstr_append_zt(&dstr, "pending\r\n");
				/* this is an error ! */
				LOG(L_ERR, "sending NOTIFY for an unitialized subscription!\n");
				break;
	}
	dstr_append_str(&dstr, &s->u.external.contact);
	
	/* required by RFC 3261 */
	dstr_append_zt(&dstr, "Max-Forwards: 70\r\n"); 
	dstr_append_zt(&dstr, "Event: ");
	dstr_append_str(&dstr, rls_get_package(s));
	dstr_append_zt(&dstr, "\r\n");
	dstr_append_zt(&dstr, "Require: eventlist\r\nContent-Type: ");
	dstr_append_str(&dstr, &content_type);
	dstr_append_zt(&dstr, "\r\n");

	res = dstr_get_str(&dstr, &headers);
	dstr_destroy(&dstr);

	if (res >= 0) {
		/* DEBUG("sending NOTIFY message to %.*s (subscription %p)\n",  
				dlg->rem_uri.len, 
				ZSW(dlg->rem_uri.s), s); */
		
		if (!is_str_empty(&doc)) body = doc;
		
		if (sm_subscription_terminated(&s->u.external) == 0) {
			/* doesn't matter if delivered or not, it will be freed otherwise !!! */
			res = tmb.t_request_within(&method, &headers, &body, dlg, 0, 0);
			if (res >= 0) clear_change_flags(s);
		}
		else {
			rls_notify_cb_param_t *cbd = create_notify_cb_param(s);
			if (!cbd) {
				ERR("Can't create notify cb data! Freeing RL subscription.\n");
				rls_remove(s); /* ?????? */
				removed = 1;
				res = -13;
			}
			else {
				/* the subscritpion will be destroyed if NOTIFY delivery problems */
				/* rls_unlock();  the callback locks this mutex ! */
				
				/* !!!! FIXME: callbacks can't be safely used (may be called or not,
				 * may free memory automaticaly or not) !!! */
				res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, cbd);
				
		/*		res = tmb.t_request_within(&method, &headers, &body, dlg, rls_notify_cb, s); */
				/* rls_lock(); the callback locks this mutex ! */
				if (res < 0) {
					/* does this mean, that the callback was not called ??? */
					ERR("t_request_within FAILED: %d! Freeing RL subscription.\n", res);
					rls_remove(s); /* ?????? */
					removed = 1;
				}
				else clear_change_flags(s);
			}
		}
	}
	
	if (doc.s) cds_free(doc.s);
	if (content_type.s) cds_free(content_type.s);
	if (headers.s) cds_free(headers.s);
	
	if ((!removed) && use_db) rls_db_update(s);
	
	if (res < 0) DEBUG("external notify NOT generated\n");
	else DEBUG("external notify generated\n");
	
	return res;
}
示例#7
0
文件: notify.c 项目: kiryu/kamailio
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;
}