Пример #1
0
/**
 * \brief This function handle node_unsubscribe command
 */
int vs_handle_node_unsubscribe(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *node_unsubscribe)
{
	struct VSNode *node;
	struct VSNodeSubscriber *node_subscriber;
	uint32 node_id = UINT32(node_unsubscribe->data[0]);
	uint32 version = UINT32(node_unsubscribe->data[UINT32_SIZE]);
	/*uint32 crc32 = UINT32(node_unsubscribe->data[UINT32_SIZE + UINT32_SIZE]);*/

	/* Try to find node */
	if((node = vs_node_find(vs_ctx, node_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) not found\n",
				__FUNCTION__, node_id);
		return 0;
	}

	/* TODO: when versing will be supported, then compute crc32, save data to
	 * the disk and send node_unsubscribe command to the client with version number
	 * and crc32 */
	if(version != 0) {
		v_print_log(VRS_PRINT_WARNING,
				"Version: %d != 0, versing is not supported yet\n", version);
	}

	/* Node has to be created */
	if(node->state == ENTITY_CREATED || node->state == ENTITY_CREATING) {
		/* Is client subscribed to this node? */
		node_subscriber = node->node_subs.first;
		while(node_subscriber != NULL) {
			if(node_subscriber->session->session_id == vsession->session_id) {
				break;
			}
			node_subscriber = node_subscriber->next;
		}
		if(node_subscriber!= NULL) {
			return vs_node_unsubscribe(node, node_subscriber, 0);
		} else {
			v_print_log(VRS_PRINT_DEBUG_MSG,
					"%s() client not subscribed to this node (id: %d)\n",
					__FUNCTION__, node_id);
			return 0;
		}
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s() node (id: %d) is not in NODE_CREATED state: %d\n",
				__FUNCTION__, node->id, node->state);
		return 0;
	}

	return 0;
}
Пример #2
0
/**
 * \brief This function do recursive unsubscribing from node
 */
static int vs_node_unsubscribe(struct VSNode *node,
		struct VSNodeSubscriber *node_subscriber,
		int level)
{
	struct VSNode *child_node;
	struct VSLink *link;
	struct VBucket *tg_bucket, *layer_bucket;
	struct VSTagGroup *tg;
	struct VSLayer *layer;
	struct VSNodeSubscriber *_node_subscriber, *_next_node_subscriber;
	struct VSEntityFollower *node_follower;
	struct VSEntityFollower	*taggroup_follower;
	struct VSEntityFollower	*layer_follower;

	/* Unsubscribe from all child nodes */
	link = node->children_links.first;
	while(link != NULL) {
		child_node = link->child;

		_node_subscriber = child_node->node_subs.first;
		while(_node_subscriber != NULL) {
			_next_node_subscriber = _node_subscriber->next;
			if(_node_subscriber->session->session_id == node_subscriber->session->session_id) {
				/* Unsubscribe from child node */
				vs_node_unsubscribe(child_node, _node_subscriber, level+1);
				break;
			}
			_node_subscriber = _next_node_subscriber;
		}

		link = link->next;
	}

	/* Unsubscribe client from all tag groups */
	tg_bucket = node->tag_groups.lb.first;
	while(tg_bucket != NULL) {
		tg = (struct VSTagGroup*)tg_bucket->data;

		/* Remove client from the list of TagGroup subscribers */
		vs_taggroup_unsubscribe(tg, node_subscriber->session);

		/* Remove client from the list of TagGroup followers */
		taggroup_follower = tg->tg_folls.first;
		while(taggroup_follower != NULL) {
			if(taggroup_follower->node_sub->session->session_id == node_subscriber->session->session_id) {
				v_list_free_item(&tg->tg_folls, taggroup_follower);
				break;
			}
			taggroup_follower = taggroup_follower->next;
		}

		tg_bucket = tg_bucket->next;
	}

	/* Unsubscribe client from all layers */
	layer_bucket = node->layers.lb.first;
	while(layer_bucket != NULL) {
		layer = (struct VSLayer*)layer_bucket->data;

		/* Remove client from the list of Layer subscribers */
		vs_layer_unsubscribe(layer, node_subscriber->session);

		/* Remove client from the list of Layer followers */
		layer_follower = layer->layer_folls.first;
		while(layer_follower != NULL) {
			if(layer_follower->node_sub->session->session_id == node_subscriber->session->session_id) {
				v_list_free_item(&layer->layer_folls, layer_follower);
				break;
			}
			layer_follower = layer_follower->next;
		}
		layer_bucket = layer_bucket->next;
	}

	if(level > 0) {
		/* Remove this session from list of followers too */
		node_follower = node->node_folls.first;
		while(node_follower != NULL) {
			if(node_follower->node_sub->session->session_id == node_subscriber->session->session_id) {
				/* Remove client from list of clients, that knows about this node */
				v_print_log(VRS_PRINT_DEBUG_MSG,
						"Removing session: %d from the list of node: %d followers\n",
						node_subscriber->session->session_id, node->id);
				v_list_free_item(&node->node_folls, node_follower);
				break;
			}
			node_follower = node_follower->next;
		}
	}

	/* Finally remove this session from list of node subscribers */
	v_list_free_item(&node->node_subs, node_subscriber);

	return 1;
}