Beispiel #1
0
static void publish_to_corosync(struct stasis_message *message)
{
	struct ast_event *event;

	event = stasis_message_to_event(message);
	if (!event) {
		return;
	}

	if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) {
		/* If the event didn't originate from this server, don't send it back out. */
		ast_event_destroy(event);
		return;
	}

	if (ast_event_get_type(event) == AST_EVENT_PING) {
		const struct ast_eid *eid;
		char buf[128] = "";

		eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
		ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid);
		ast_log(LOG_NOTICE, "Sending event PING from this server with EID: '%s'\n", buf);
	}

	publish_event_to_corosync(event);
}
Beispiel #2
0
static void cpg_deliver_cb(cpg_handle_t handle, const struct cpg_name *group_name,
		uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
{
	struct ast_event *event;
	void (*publish_handler)(struct ast_event *) = NULL;
	enum ast_event_type event_type;

	if (msg_len < ast_event_minimum_length()) {
		ast_debug(1, "Ignoring event that's too small. %u < %u\n",
			(unsigned int) msg_len,
			(unsigned int) ast_event_minimum_length());
		return;
	}

	if (!ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(msg, AST_EVENT_IE_EID))) {
		/* Don't feed events back in that originated locally. */
		return;
	}

	event_type = ast_event_get_type(msg);
	if (event_type > AST_EVENT_TOTAL) {
		/* Egads, we don't support this */
		return;
	}

	ast_rwlock_rdlock(&event_types_lock);
	publish_handler = event_types[event_type].publish_to_stasis;
	if (!event_types[event_type].subscribe || !publish_handler) {
		/* We are not configured to subscribe to these events or
		   we have no way to publish it internally. */
		ast_rwlock_unlock(&event_types_lock);
		return;
	}
	ast_rwlock_unlock(&event_types_lock);

	if (!(event = ast_malloc(msg_len))) {
		return;
	}

	memcpy(event, msg, msg_len);

	if (event_type == AST_EVENT_PING) {
		const struct ast_eid *eid;
		char buf[128] = "";

		eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
		ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid);
		ast_log(LOG_NOTICE, "Got event PING from server with EID: '%s'\n", buf);
	}
	ast_debug(5, "Publishing event %s (%u) to stasis\n",
		ast_event_get_type_name(event), event_type);
	publish_handler(event);
}
Beispiel #3
0
/*! \brief Publish a received device state \ref ast_event to \ref stasis */
static void publish_device_state_to_stasis(struct ast_event *event)
{
	const char *device;
	enum ast_device_state state;
	unsigned int cachable;
	struct ast_eid *event_eid;

	ast_assert(ast_event_get_type(event) == AST_EVENT_DEVICE_STATE_CHANGE);

	device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
	state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
	cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
	event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID);

	if (ast_strlen_zero(device)) {
		return;
	}

	if (ast_publish_device_state_full(device, state, cachable, event_eid)) {
		char eid[18];
		ast_eid_to_str(eid, sizeof(eid), event_eid);
		ast_log(LOG_WARNING, "Failed to publish device state message for %s from %s\n",
			device, eid);
	}
}
Beispiel #4
0
static void cpg_deliver_cb(cpg_handle_t handle, const struct cpg_name *group_name,
		uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
{
	struct ast_event *event;

	if (msg_len < ast_event_minimum_length()) {
		ast_debug(1, "Ignoring event that's too small. %u < %u\n",
			(unsigned int) msg_len,
			(unsigned int) ast_event_minimum_length());
		return;
	}

	if (!ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(msg, AST_EVENT_IE_EID))) {
		/* Don't feed events back in that originated locally. */
		return;
	}

	ast_rwlock_rdlock(&event_types_lock);
	if (!event_types[ast_event_get_type(msg)].subscribe) {
		/* We are not configured to subscribe to these events. */
		ast_rwlock_unlock(&event_types_lock);
		return;
	}
	ast_rwlock_unlock(&event_types_lock);

	if (!(event = ast_malloc(msg_len))) {
		return;
	}

	memcpy(event, msg, msg_len);

	ast_event_queue_and_cache(event);
}
Beispiel #5
0
static void publish_to_corosync(struct stasis_message *message)
{
	cs_error_t cs_err;
	struct iovec iov;
	struct ast_event *event;

	event = stasis_message_to_event(message);
	if (!event) {
		return;
	}

	if (ast_eid_cmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID))) {
		/* If the event didn't originate from this server, don't send it back out. */
		ast_event_destroy(event);
		return;
	}

	if (ast_event_get_type(event) == AST_EVENT_PING) {
		const struct ast_eid *eid;
		char buf[128] = "";

		eid = ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
		ast_eid_to_str(buf, sizeof(buf), (struct ast_eid *) eid);
		ast_log(LOG_NOTICE, "Sending event PING from this server with EID: '%s'\n", buf);
	}

	iov.iov_base = (void *)event;
	iov.iov_len = ast_event_get_size(event);

	ast_debug(5, "Publishing event %s (%u) to corosync\n",
		ast_event_get_type_name(event), ast_event_get_type(event));

	/* The stasis subscription will only exist if we are configured to publish
	 * these events, so just send away. */
	if ((cs_err = cpg_mcast_joined(cpg_handle, CPG_TYPE_FIFO, &iov, 1)) != CS_OK) {
		ast_log(LOG_WARNING, "CPG mcast failed (%u)\n", cs_err);
	}
}
Beispiel #6
0
static struct corosync_node *corosync_node_alloc(struct ast_event *event)
{
	struct corosync_node *node;

	node = ao2_alloc_options(sizeof(*node), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
	if (!node) {
		return NULL;
	}

	memcpy(&node->eid, (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID), sizeof(node->eid));
	node->id = ast_event_get_ie_uint(event, AST_EVENT_IE_NODE_ID);
	ast_sockaddr_parse(&node->addr, ast_event_get_ie_str(event, AST_EVENT_IE_LOCAL_ADDR), PARSE_PORT_IGNORE);

	return node;
}
Beispiel #7
0
/*! \brief Publish a received cluster discovery \ref ast_event to \ref stasis */
static void publish_cluster_discovery_to_stasis(struct ast_event *event)
{
	struct corosync_node *node;
	int id = ast_event_get_ie_uint(event, AST_EVENT_IE_NODE_ID);
	struct ast_eid *event_eid;

	ast_assert(ast_event_get_type(event) == AST_EVENT_CLUSTER_DISCOVERY);

	event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID);
	if (!ast_eid_cmp(&ast_eid_default, event_eid)) {
		/* Don't feed events back in that originated locally. */
		return;
	}

	ao2_lock(nodes);
	node = ao2_find(nodes, &id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (node) {
		/* We already know about this node */
		ao2_unlock(nodes);
		ao2_ref(node, -1);
		return;
	}

	node = corosync_node_alloc(event);
	if (!node) {
		ao2_unlock(nodes);
		return;
	}
	ao2_link_flags(nodes, node, OBJ_NOLOCK);
	ao2_unlock(nodes);

	publish_cluster_discovery_to_stasis_full(node, 1);

	ao2_ref(node, -1);

	/*
	 * When we get news that someone else has joined, we need to let them
	 * know we exist as well.
	 */
	send_cluster_notify();
}
Beispiel #8
0
/*! \brief Publish a received MWI \ref ast_event to \ref stasis */
static void publish_mwi_to_stasis(struct ast_event *event)
{
	const char *mailbox;
	const char *context;
	unsigned int new_msgs;
	unsigned int old_msgs;
	struct ast_eid *event_eid;

	ast_assert(ast_event_get_type(event) == AST_EVENT_MWI);

	mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
	context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
	new_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
	old_msgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
	event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID);

	if (ast_strlen_zero(mailbox) || ast_strlen_zero(context)) {
		return;
	}

	if (new_msgs > INT_MAX) {
		new_msgs = INT_MAX;
	}

	if (old_msgs > INT_MAX) {
		old_msgs = INT_MAX;
	}

	if (ast_publish_mwi_state_full(mailbox, context, (int)new_msgs,
	                               (int)old_msgs, NULL, event_eid)) {
		char eid[18];
		ast_eid_to_str(eid, sizeof(eid), event_eid);
		ast_log(LOG_WARNING, "Failed to publish MWI message for %s@%s from %s\n",
			mailbox, context, eid);
	}
}
Beispiel #9
0
/*! \brief Convert a Corosync PING to a \ref ast_event */
static struct ast_event *corosync_ping_to_event(struct stasis_message *message)
{
	struct corosync_ping_payload *payload;
	struct ast_event *event;
	struct ast_eid *event_eid;

	if (!message) {
		return NULL;
	}

	payload = stasis_message_data(message);

	if (!payload->event) {
		return NULL;
	}

	event_eid = (struct ast_eid *)ast_event_get_ie_raw(payload->event, AST_EVENT_IE_EID);

	event = ast_event_new(AST_EVENT_PING,
				AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, event_eid, sizeof(*event_eid),
				AST_EVENT_IE_END);

	return event;
}
Beispiel #10
0
static int ie_is_present(const struct ast_event *event,
                         const enum ast_event_ie_type ie_type)
{
    return (ast_event_get_ie_raw(event, ie_type) != NULL);
}
Beispiel #11
0
static int check_event(struct ast_event *event, struct ast_test *test,
		enum ast_event_type expected_type, const char *type_name,
		const char *str, uint32_t uint, uint32_t bitflags)
{
	enum ast_event_type type;
	const void *foo;

	/* Check #1: Ensure event type is set properly. */
	type = ast_event_get_type(event);
	if (ast_event_get_type(event) != type) {
		ast_test_status_update(test, "Expected event type: '%d', got '%d'\n",
				expected_type, type);
		return -1;
	}

	/* Check #2: Check string representation of event type */
	if (strcmp(type_name, ast_event_get_type_name(event))) {
		ast_test_status_update(test, "Didn't get expected type name: '%s' != '%s'\n",
				type_name, ast_event_get_type_name(event));
		return -1;
	}

	/* Check #3: Check for automatically included EID */
	if (memcmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID), sizeof(ast_eid_default))) {
		ast_test_status_update(test, "Failed to get EID\n");
		return -1;
	}

	/* Check #4: Check for the string IE */
	if (strcmp(str, ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX))) {
		ast_test_status_update(test, "Failed to get string IE.\n");
		return -1;
	}

	/* Check #5: Check for the uint IE */
	if (uint != ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS)) {
		ast_test_status_update(test, "Failed to get uint IE.\n");
		return -1;
	}

	/* Check #6: Check for the bitflags IE */
	if (bitflags != ast_event_get_ie_bitflags(event, AST_EVENT_IE_OLDMSGS)) {
		ast_test_status_update(test, "Failed to get bitflags IE.\n");
		return -1;
	}

	/* Check #7: Check if a check for a str IE that isn't there works */
	if ((foo = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE))) {
		ast_test_status_update(test, "DEVICE IE check returned non-NULL %p\n", foo);
		return -1;
	}

	/* Check #8: Check if a check for a uint IE that isn't there returns 0 */
	if (ast_event_get_ie_uint(event, AST_EVENT_IE_STATE)) {
		ast_test_status_update(test, "OLDMSGS IE should be 0\n");
		return -1;
	}

	ast_test_status_update(test, "Event looks good.\n");

	return 0;
}