Esempio n. 1
0
static evi_subs_p evi_get_subscriber(evi_event_p event, str sock_str)
{
	evi_export_t * trans_mod;
	evi_subs_p subscriber = NULL;
	evi_reply_sock * sock;

	/* transport module name */
	trans_mod = get_trans_mod(&sock_str);
	if (!trans_mod) {
		LM_DBG("couldn't find a protocol to support %.*s\n",
				sock_str.len, sock_str.s);
		return NULL;
	}
	sock_str.s += trans_mod->proto.len + 1;
	sock_str.len -= (trans_mod->proto.len + 1);

	/* parse reply socket */
	sock = trans_mod->parse(sock_str);
	if (!sock)
		return NULL;

	/* tries to match other socket */
	if (trans_mod->match) {
		lock_get(event->lock);
		for (subscriber = event->subscribers; subscriber;
				subscriber = subscriber->next) {
			if (subscriber->trans_mod != trans_mod)
				continue;
			if (trans_mod->match(sock, subscriber->reply_sock)) {
				if (trans_mod->free)
					trans_mod->free(sock);
				else
					shm_free(sock);
				break;
			}
		}
		lock_release(event->lock);
	}
	return subscriber;
}
struct mi_root * mi_event_subscribe(struct mi_root *root, void *param )
{
	struct mi_node *node;
	evi_subs_t *subscriber = NULL;
	evi_event_p event;
	evi_export_t *trans_mod = NULL;
	evi_reply_sock *sock;
	str sock_str;
	unsigned int expire = 0;

	/* event name */
	node = root->node.kids;
	if (!node) {
		LM_ERR("no parameters received\n");
		goto missing_param;
	}

	event = evi_get_event(&node->value);
	if (!event) {
		LM_ERR("invalid event name <%.*s>\n",
				node->value.len, node->value.s);
		goto bad_param;
	}

	/* transport module name */
	node = node->next;
	if (!node) {
		LM_ERR("no transport type\n");
		goto missing_param;
	}

	trans_mod = get_trans_mod(&node->value);
	if (!trans_mod) {
		LM_ERR("couldn't find a protocol to support %.*s\n",
				node->value.len,node->value.s);
		goto bad_param;
	}
	sock_str.s = node->value.s + trans_mod->proto.len + 1;
	sock_str.len = node->value.len - trans_mod->proto.len - 1;

	/* check expire */
	node = node->next;
	if (node) {
		/* expiration period is set */
		if (str2int(&node->value, &expire) < 0) {
			LM_ERR("invalid expire value %.*s", node->value.len, node->value.s);
			goto bad_param;
		}
	} else
		expire = DEFAULT_EXPIRE;


	/* parse reply socket */
	sock = trans_mod->parse(sock_str);
	if (!sock)
		goto bad_param;

	/* tries to match other socket */
	if (trans_mod->match) {
		lock_get(event->lock);
		for (subscriber = event->subscribers; subscriber;
				subscriber = subscriber->next) {
			if (subscriber->trans_mod != trans_mod)
				continue;
			if (trans_mod->match(sock, subscriber->reply_sock)) {
				/* update subscription time */
				subscriber->reply_sock->subscription_time = time(0);
				/* update expire if required */
				if (EVI_EXPIRE & sock->flags)
					subscriber->reply_sock->expire = expire;
				if (trans_mod->free)
					trans_mod->free(sock);
				else 
					shm_free(sock);
				break;
			}
		}
		lock_release(event->lock);
	}

	/* if no socket matches - create a new one */
	if (!subscriber) {
		subscriber = shm_malloc(sizeof(evi_subs_t));
		if (!subscriber) {
			LM_ERR("no more shm memory\n");
			goto internal_error;
		}

		sock->subscription_time = time(0);
		subscriber->trans_mod = trans_mod;
		subscriber->reply_sock = sock;

		if (EVI_EXPIRE & sock->flags)
			subscriber->reply_sock->expire = expire;
		subscriber->reply_sock->flags |= trans_mod->flags;
		
		/* guard subscribers list */
		lock_get(event->lock);
		subscriber->next = event->subscribers;
		event->subscribers = subscriber;
		lock_release(event->lock);
		LM_DBG("added new subscriber for event %d\n", event->id);
	}

	return init_mi_tree(200, MI_SSTR(MI_OK));
	
internal_error:
	if (trans_mod && sock) {
		/* if the module has it's own free function */
		if (trans_mod->free)
			trans_mod->free(sock);
		else
			shm_free(sock);
	}
	return init_mi_tree(500, MI_SSTR(MI_INTERNAL_ERR));

missing_param:
	return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));

bad_param:
	return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
}
Esempio n. 3
0
/*
 * Subscribes an event
 * Returns:
 *  1 - success
 *  0 - internal error
 * -1 - param error
 */
int evi_event_subscribe(str event_name,
		str sock_str, unsigned expire, unsigned unsubscribe)
{
	evi_subs_t *subscriber = NULL;
	evi_event_p event;
	evi_export_t *trans_mod = NULL;
	evi_reply_sock *sock;

	event = evi_get_event(&event_name);
	if (!event) {
		LM_ERR("invalid event name <%.*s>\n",
				event_name.len, event_name.s);
		goto bad_param;
	}

	/* transport module name */
	trans_mod = get_trans_mod(&sock_str);
	if (!trans_mod) {
		LM_ERR("couldn't find a protocol to support %.*s\n",
				sock_str.len, sock_str.s);
		goto bad_param;
	}
	sock_str.s += trans_mod->proto.len + 1;
	sock_str.len -= (trans_mod->proto.len + 1);

	/* parse reply socket */
	sock = trans_mod->parse(sock_str);
	if (!sock)
		goto bad_param;
	/* reset unrequired flags */
	if (!expire && !unsubscribe)
		sock->flags &= ~EVI_EXPIRE;

	/* tries to match other socket */
	if (trans_mod->match) {
		lock_get(event->lock);
		for (subscriber = event->subscribers; subscriber;
				subscriber = subscriber->next) {
			if (subscriber->trans_mod != trans_mod)
				continue;
			if (trans_mod->match(sock, subscriber->reply_sock)) {
				/* update subscription time */
				subscriber->reply_sock->subscription_time = time(0);
				/* update expire if required */
				if (EVI_EXPIRE & sock->flags) {
					subscriber->reply_sock->expire = expire;
					subscriber->reply_sock->flags = sock->flags;
				}
				if (trans_mod->free)
					trans_mod->free(sock);
				else
					shm_free(sock);
				break;
			}
		}
		lock_release(event->lock);
	}

	/* if no socket matches - create a new one */
	if (!subscriber) {
		subscriber = shm_malloc(sizeof(evi_subs_t));
		if (!subscriber) {
			LM_ERR("no more shm memory\n");
			if (trans_mod && sock) {
				/* if the module has it's own free function */
				if (trans_mod->free)
					trans_mod->free(sock);
				else
					shm_free(sock);
			}
			return 0;
		}

		sock->subscription_time = time(0);
		subscriber->trans_mod = trans_mod;
		subscriber->reply_sock = sock;

		if (EVI_EXPIRE & sock->flags)
			subscriber->reply_sock->expire = expire;
		subscriber->reply_sock->flags |= trans_mod->flags;

		/* guard subscribers list */
		lock_get(event->lock);
		subscriber->next = event->subscribers;
		event->subscribers = subscriber;
		lock_release(event->lock);
		LM_DBG("added new subscriber for event %d\n", event->id);
	}

	return 1;
bad_param:
	return -1;
}