예제 #1
0
파일: watcher.c 프로젝트: 4N7HR4X/kamailio
/*
 * Create a new watcher structure but do not write to database
 */
int new_watcher_no_wb(str* _uri, time_t _e, int event_package, 
		int doc_type, dlg_t* _dlg, str *_dn, str *server_contact, 
		str *id, watcher_t** _w)
{
	watcher_t* watcher;
	int size;
	dbid_t dbid;
	str sid;

	/* Check parameters */
	if (!_uri && !_dlg && !_w) {
		LOG(L_ERR, "new_watcher(): Invalid parameter value\n");
		return -1;
	}

	if (!id) {
		/* generate new database/watcher id (needed for winfo documents!) */
		generate_dbid(dbid);
		sid.s = dbid_strptr(dbid);
		sid.len = dbid_strlen(dbid);
		id = &sid;
	}
	
	/* Allocate memory buffer for watcher_t structure and uri string */
	size = sizeof(watcher_t) + id->len + _uri->len + _dn->len + server_contact->len;
	watcher = (watcher_t*)mem_alloc(size);
	if (!watcher) {
		paerrno = PA_NO_MEMORY;
        ERR("No memory left (%d bytes)\n", size);
		return -1;
	}
	memset(watcher, 0, sizeof(watcher_t));

	/* Copy ID string */
	watcher->id.s = (char*)watcher + sizeof(watcher_t);
	str_cpy(&watcher->id, id);
	
	/* Copy uri string */
	watcher->uri.s = after_str_ptr(&watcher->id);
	str_cpy(&watcher->uri, _uri);
	
	/* Copy display_name string */
	watcher->display_name.s = after_str_ptr(&watcher->uri);
	str_cpy(&watcher->display_name, _dn);
	
	/* Copy server_contact string */
	watcher->server_contact.s = after_str_ptr(&watcher->display_name);
	str_cpy(&watcher->server_contact, server_contact);

	watcher->document_index = 0;
	watcher->event_package = event_package;
	watcher->expires = _e; /* Expires value */
	watcher->preferred_mimetype = doc_type;  /* Accepted document type */
	watcher->dialog = _dlg; /* Dialog handle */
	watcher->event = WE_SUBSCRIBE;
	watcher->status = WS_PENDING;
	
	*_w = watcher;

	return 0;
}
예제 #2
0
/* Create a new presentity but do not update database.
 * If pres_id not set it generates new one, but only if db_mode set. */
static inline int new_presentity_no_wb(struct pdomain *pdomain, str* _uri, 
		str *uid, 
		xcap_query_params_t *xcap_params,
		str *pres_id,
		presentity_t** _p)
{
	presentity_t* presentity;
	int size = 0;
	dbid_t id;
	int id_len = 0;
	char *xcap_param_buffer;
	
	if ((!_uri) || (!_p) || (!uid)) {
		paerrno = PA_INTERNAL_ERROR;
		ERR("Invalid parameter value\n");
		return -1;
	}

	if (pres_id) size += pres_id->len;
	else {
		if (use_db) { /* do not generate IDs if not using DB */
			generate_dbid(id);
			id_len = dbid_strlen(id);
			size += id_len;
		}
		else id_len = 0;
	}

	if (xcap_params) size += get_inline_xcap_buf_len(xcap_params);
	size += sizeof(presentity_t) + _uri->len + uid->len;
	presentity = (presentity_t*)mem_alloc(size);
	/* TRACE("allocating presentity: %d\n", size); */
	if (!presentity) {
		paerrno = PA_NO_MEMORY;
		LOG(L_ERR, "No memory left: size=%d\n", size);
		*_p = NULL;
		return -1;
	}

	/* fill whole structure with zeros */
	memset(presentity, 0, sizeof(presentity_t));

	msg_queue_init(&presentity->mq);

	presentity->data.uri.s = ((char*)presentity) + sizeof(presentity_t);	
	str_cpy(&presentity->data.uri, _uri);
	presentity->uuid.s = presentity->data.uri.s + presentity->data.uri.len;
	str_cpy(&presentity->uuid, uid);
	presentity->pres_id.s = presentity->uuid.s + presentity->uuid.len;
	if (pres_id) str_cpy(&presentity->pres_id, pres_id);
	else {
		if (use_db) dbid_strcpy(&presentity->pres_id, id, id_len);
		else presentity->pres_id.len = 0;
	}
	xcap_param_buffer = after_str_ptr(&presentity->pres_id);
			
	presentity->pdomain = pdomain;

	if (pa_auth_params.type == auth_xcap) { 
		/* store XCAP parameters for async XCAP queries and refreshing
		 * (FIXME: rewrite - use table of a few of existing XCAP parameter
		 * sets instead of always duplicating because it will be mostly 
		 * the same!) */
		if (dup_xcap_params_inline(&presentity->xcap_params, xcap_params, 
					xcap_param_buffer) < 0) {
			ERR("can't duplicate XCAP parameters\n");
			shm_free(presentity);
			*_p = NULL;
			return -1;
		}
	}
	if (ask_auth_rules(presentity) < 0) {
		/* try it from timer again if fails here */
		presentity->auth_rules_refresh_time = act_time;
	}
	else presentity->auth_rules_refresh_time = act_time + auth_rules_refresh_time;
	
	*_p = presentity;

	/* add presentity into domain */
	add_presentity(pdomain, *_p);

	return 0;
}
예제 #3
0
static int publish_presence(struct sip_msg* _m, struct presentity* presentity)
{
	char *body = get_body(_m);
	int body_len = 0;
	int msg_expires = default_expires;
	time_t expires = 0;
	str etag;
	dbid_t generated_etag;
	int has_etag;
	presentity_info_t *p = NULL;
	int content_type = -1;
	
	if (_m->content_type) content_type = get_content_type(_m);
	if (_m->content_length) body_len = get_content_length(_m);
	
	if (_m->expires) {
		if (_m->expires->parsed) {
			msg_expires = ((exp_body_t*)_m->expires->parsed)->val;
		}
	}
	if (msg_expires > max_publish_expiration) 
		msg_expires = max_publish_expiration;
	if (msg_expires != 0) expires = msg_expires + act_time;

	if (_m->sipifmatch) {
		if (_m->sipifmatch->parsed) 
			etag = *(str*)_m->sipifmatch->parsed;
		else str_clear(&etag);
		has_etag = 1;
	}
	else {
		/* ETag was not set, generate a new one */
		generate_dbid(generated_etag);
		etag.len = dbid_strlen(generated_etag);
		etag.s = dbid_strptr(generated_etag);
		has_etag = 0;
	}

	if (body_len > 0) {
		switch (content_type) {
			case MIMETYPE(APPLICATION,PIDFXML):
				if (parse_pidf_document(&p, body, body_len) != 0) {
					LOG(L_ERR, "can't parse PIDF document\n");
					paerrno = PA_UNSUPP_DOC; /* ? PA_PARSE_ERR */
				}
				break;
			case MIMETYPE(APPLICATION,CPIM_PIDFXML):
				if (parse_cpim_pidf_document(&p, body, body_len) != 0) {
					LOG(L_ERR, "can't parse CPIM-PIDF document\n");
					paerrno = PA_UNSUPP_DOC;
				}
				break;
			default:
				LOG(L_ERR, "unsupported Content-Type 0x%x for PUBLISH handling\n", 
						content_type);
				paerrno = PA_UNSUPP_DOC;
		}
		
		if (paerrno != PA_OK) return -1;
	}
	
	if (process_published_presentity_info(presentity, p, &etag, 
				expires, has_etag) == 0) {
		/* add header fields into response */
		add_expires_to_rpl(_m, msg_expires);
		add_etag_to_rpl(_m, &etag);
	}
	if (p) free_presentity_info(p);
	
	return 0;
}