コード例 #1
0
ファイル: vs_layer.c プロジェクト: GitReinDa/verse
int vs_handle_layer_destroy(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_destroy_cmd)
{
	struct VSNode *node;
	struct VSLayer *layer;
	struct VSUser *user;

	uint32 node_id = UINT32(layer_destroy_cmd->data[0]);
	uint16 layer_id = UINT16(layer_destroy_cmd->data[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;
	}

	/* Node has to be created */
	if(!(node->state == ENTITY_CREATED || node->state == ENTITY_CREATING)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) is not in CREATING or CREATED state: %d\n",
				__FUNCTION__, node->id, node->state);
		return 0;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to write to the node */
	if(vs_node_can_write(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

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

	/* Layer has to be created */
	if(! (layer->state == ENTITY_CREATING || layer->state == ENTITY_CREATED)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer (id: %u) in node (id: %d) is not in CREATED state: %d\n",
				__FUNCTION__, layer->id, node->id, node->state);
		return 0;
	}

	layer->state = ENTITY_DELETING;

	return vs_layer_send_destroy(node, layer);
}
コード例 #2
0
ファイル: vs_layer.c プロジェクト: GitReinDa/verse
/**
 * \brief This function handle command layer_unset_value
 */
int vs_handle_layer_unset_value(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_unset_value_cmd)
{
	struct VSNode *node;
	struct VSLayer *layer;
	struct VSUser *user;

	uint32 node_id = UINT32(layer_unset_value_cmd->data[0]);
	uint16 layer_id = UINT16(layer_unset_value_cmd->data[UINT32_SIZE]);
	uint32 item_id = UINT32(layer_unset_value_cmd->data[UINT32_SIZE + UINT16_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;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to write to the node */
	if(vs_node_can_write(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to the node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

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

	return vs_layer_unset_value(node, layer, item_id, 1);
}
コード例 #3
0
ファイル: vs_node.c プロジェクト: zdenek-perutka/verse
/**
 * \brief This function tries to handle node_destroy command
 */
int vs_handle_node_destroy(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *node_destroy)
{
	struct VSUser *user;
	struct VSNode *node;
	uint32 node_id = UINT32(node_destroy->data[0]);

	/* 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;
	}

	/* Node has to be created */
	if(! (node->state == ENTITY_CREATED || node->state == ENTITY_CREATING)) {
		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;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "vsession->user_id: %d not found\n", vsession->user_id);
		return 0;
	}

	/* Is this user owner of this node? */
	if(user != node->owner) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"user_id: %d is not owner of the node (id: %d) and can't delete this node.\n",
				vsession->user_id, node->id);
		return 0;
	}

	return vs_node_send_destroy(node);
}
コード例 #4
0
ファイル: vs_node.c プロジェクト: jesterKing/verse
/**
 * \brief This function creates new node at verse server, when client sent
 * node_create command.
 */
static struct VSNode *vs_node_new(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		const uint16 type)
{
	struct VSNode *node = NULL;
	struct VSNode find_node, *avatar_node;
	struct VSUser *owner;
	struct VBucket *bucket;
	struct VSNodePermission *perm;
	struct VSNodeSubscriber *node_subscriber;

	/* Try to find avatar node to be able to create initial link to
	 * avatar node (initial parent of new created node) */
	find_node.id = vsession->avatar_id;
	bucket = v_hash_array_find_item(&vs_ctx->data.nodes, &find_node);
	if(bucket != NULL) {
		avatar_node = (struct VSNode*)bucket->data;
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG, "vsession->avatar_id: %d not found\n", vsession->avatar_id);
		goto end;
	}

	/* Try to find owner of the new node */
	if((owner = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "vsession->user_id: %d not found\n", vsession->user_id);
		goto end;
	}

	/* Try to create new verse node */
	if( (node = vs_node_create(vs_ctx, avatar_node, owner, VRS_RESERVED_NODE_ID, type)) == NULL) {
		goto end;
	}

	/* Set initial state of this node */
	node->state = ENTITY_CREATING;

	/* Find node representing fake user other_users */
	if( vs_ctx->other_users != NULL) {
		/* Set access permissions for other users */
		perm = (struct VSNodePermission *)calloc(1, sizeof(struct VSNodePermission));
		perm->user = vs_ctx->other_users;

		/* TODO: implement default session permissions and use them,
		 * when are available */

		perm->permissions = vs_ctx->default_perm;
		v_list_add_tail(&node->permissions, perm);
	}

	/* Send node_create to all subscribers of avatar node data */
	node_subscriber = avatar_node->node_subs.first;
	while(node_subscriber) {
		vs_node_send_create(node_subscriber, node, avatar_node);
		node_subscriber = node_subscriber->next;
	}


end:

	return node;
}
コード例 #5
0
ファイル: vs_layer.c プロジェクト: GitReinDa/verse
int vs_handle_layer_set_value(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_set_value_cmd,
		uint8 data_type,
		uint8 count)
{
	struct VSNode *node;
	struct VSLayer *layer;
	struct VSLayerValue *item, _item;
	struct VBucket *vbucket;
	struct VSUser *user;
	struct VSEntitySubscriber *layer_subscriber;

	uint32 node_id = UINT32(layer_set_value_cmd->data[0]);
	uint16 layer_id = UINT16(layer_set_value_cmd->data[UINT32_SIZE]);
	uint32 item_id = UINT32(layer_set_value_cmd->data[UINT32_SIZE + UINT16_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;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to write to the node */
	if(vs_node_can_write(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to the node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

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

	/* Check type of value */
	if( data_type != layer->data_type ) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() data type (%d) of layer (id: %d) in node (id: %d) does not match data type of received command (%d)\n",
				__FUNCTION__, layer->data_type, layer_id, node_id, data_type);
		return 0;
	}

	/* Check count of value */
	if( count != layer->num_vec_comp ) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() count of values (%d) of layer (id: %d) in node (id: %d) does not match count of values of received command (%d)\n",
				__FUNCTION__, layer->num_vec_comp, layer_id, node_id, count);
		return 0;
	}

	/* Set item value */

	/* Try to find item value first */
	_item.id = item_id;
	vbucket = v_hash_array_find_item(&layer->values, &_item);
	if(vbucket == NULL) {
		/* When this item doesn't exist yet, then allocate memory for this item
		 * and add it to the hashed array */
		item = calloc(1, sizeof(struct VSLayerValue));
		item->id = item_id;
		v_hash_array_add_item(&layer->values, item, sizeof(struct VSLayerValue));

		/* Allocate memory for values and copy data to this memory */
		switch(layer->data_type) {
			case VRS_VALUE_TYPE_UINT8:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(uint8));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT8_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT16:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(uint16));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT16_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT32:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(uint32));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT32_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT64:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(uint64));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT64_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL16:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(real16));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL16_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL32:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(real32));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL32_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL64:
				item->value = (void*)calloc(layer->num_vec_comp, sizeof(real64));
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL64_SIZE);
				break;
			default:
				return 0;
		}
	} else {
		item = (struct VSLayerValue*)vbucket->data;
		switch(layer->data_type) {
			case VRS_VALUE_TYPE_UINT8:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT8_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT16:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT16_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT32:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT32_SIZE);
				break;
			case VRS_VALUE_TYPE_UINT64:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*UINT64_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL16:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL16_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL32:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL32_SIZE);
				break;
			case VRS_VALUE_TYPE_REAL64:
				memcpy(item->value,
						&layer_set_value_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT32_SIZE],
						layer->num_vec_comp*REAL64_SIZE);
				break;
			default:
				return 0;
		}
	}

	/* Send item value set to all layer subscribers */
	layer_subscriber = layer->layer_subs.first;
	while(layer_subscriber != NULL) {
		vs_layer_send_set_value(layer_subscriber, node, layer, item);
		layer_subscriber = layer_subscriber->next;
	}

	return 1;
}
コード例 #6
0
ファイル: vs_layer.c プロジェクト: GitReinDa/verse
int vs_handle_layer_subscribe(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_subscribe_cmd)
{
	struct VSNode *node;
	struct VSUser *user;
	struct VSLayer *layer;
	struct VSNodeSubscriber *node_subscriber;
	struct VSEntitySubscriber *layer_subscriber;
	struct VBucket *vbucket;
	struct VSLayerValue *value;

	uint32 node_id = UINT32(layer_subscribe_cmd->data[0]);
	uint16 layer_id = UINT16(layer_subscribe_cmd->data[UINT32_SIZE]);
/*
	uint32 version = UINT32(layer_subscribe_cmd->data[UINT32_SIZE+UINT16_SIZE]);
	uint32 crc32 = UINT32(layer_subscribe_cmd->data[UINT32_SIZE+UINT16_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;
	}

	/* Node has to be created */
	if(!(node->state == ENTITY_CREATED || node->state == ENTITY_CREATING)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) is not in CREATING or CREATED state: %d\n",
				__FUNCTION__, node->id, node->state);
		return 0;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to read the node */
	if(vs_node_can_read(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't read the node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

	/* Try to find node subscriber */
	node_subscriber = node->node_subs.first;
	while(node_subscriber != NULL) {
		if(node_subscriber->session == vsession) {
			break;
		}
		node_subscriber = node_subscriber->next;
	}

	/* Client has to be subscribed to the node first */
	if(node_subscriber == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): client has to be subscribed to the node: %d before subscribing to the layer: %d\n",
				__FUNCTION__, node_id, layer_id);
		return 0;
	}

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

	/* Layer has to be created */
	if(! (layer->state == ENTITY_CREATING || layer->state == ENTITY_CREATED)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer (id: %u) in node (id: %d) is not in CREATED state: %d\n",
				__FUNCTION__, layer->id, node->id, node->state);
		return 0;
	}

	/* Try to find layer subscriber (client can't be subscribed twice) */
	layer_subscriber = layer->layer_subs.first;
	while(layer_subscriber != NULL) {
		if(layer_subscriber->node_sub->session->session_id == vsession->session_id) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "%s() client already subscribed to the layer (id: %d) in node (id: %d)\n",
									__FUNCTION__, layer_id, node_id);
			return 0;
		}
		layer_subscriber = layer_subscriber->next;
	}

	/* Add new subscriber to the list of layer subscribers */
	layer_subscriber = (struct VSEntitySubscriber*)malloc(sizeof(struct VSEntitySubscriber));
	layer_subscriber->node_sub = node_subscriber;
	v_list_add_tail(&layer->layer_subs, layer_subscriber);

	/* Send value set for all items in this layer
	 * TODO: do not push all values to outgoing queue at once, when there is lot
	 * of values in this layer. Implement this, when queue limits will be
	 * finished. */
	vbucket = layer->values.lb.first;
	while(vbucket != NULL) {
		value = (struct VSLayerValue*)vbucket->data;
		vs_layer_send_set_value(layer_subscriber, node, layer, value);
		vbucket = vbucket->next;
	}

	return 1;
}
コード例 #7
0
ファイル: vs_layer.c プロジェクト: GitReinDa/verse
/**
 * \brief This function is called, when server receives command layer_create
 *
 * \param[in]	*vs_ctx				The pointer at verse server context
 * \param[in]	*vsession			The pointer at session of client that sent this command
 * \param[in]	*layer_create_cmd	The pointer at received command
 *
 * \return This function returns 0, when parameters of received command are
 * wrong. When all parameters are right, then it returns 1.
 */
int vs_handle_layer_create(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_create_cmd)
{
	struct VSNode *node;
	struct VSUser *user;
	struct VSLayer *parent_layer;
	struct VSLayer *layer;
	struct VBucket *vbucket;
	struct VSNodeSubscriber *node_subscriber;

	uint32 node_id = UINT32(layer_create_cmd->data[0]);
	uint16 parent_layer_id = UINT16(layer_create_cmd->data[UINT32_SIZE]);
	uint16 layer_id = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE]);
	uint8 data_type = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE]);
	uint8 count = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE+UINT8_SIZE]);
	uint16 type = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE+UINT8_SIZE+UINT8_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;
	}

	/* When parent layer id is not -1, then try to find this parent layer */
	if(parent_layer_id == RESERVED_LAYER_ID) {
		parent_layer = NULL;
	} else {
		parent_layer = vs_layer_find(node, parent_layer_id);
		if(parent_layer == NULL) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "%s() parent layer (id: %d) in node (id: %d) not found\n",
					__FUNCTION__, parent_layer_id, node_id);
			return 0;
		}
	}

	/* Node has to be created */
	if(!(node->state == ENTITY_CREATED || node->state == ENTITY_CREATING)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) is not in CREATING or CREATED state: %d\n",
				__FUNCTION__, node->id, node->state);
		return 0;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to write to the node */
	if(vs_node_can_write(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

	/* Client has to send layer_create command with layer_id equal to
	 * the value 0xFFFF */
	if(layer_id != RESERVED_LAYER_ID) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer_id: %d is not 0xFFFF\n",
				__FUNCTION__, layer_id);
		return 0;
	}

	/* Is type of Layer supported? */
	if(!(data_type>VRS_VALUE_TYPE_RESERVED && data_type<=VRS_VALUE_TYPE_REAL64)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() data_type: %d is not supported\n",
				__FUNCTION__, data_type);
		return 0;
	}

	vbucket = node->layers.lb.first;
	/* Check, if there isn't tag with the same type */
	while(vbucket != NULL) {
		layer = vbucket->data;
		if(layer->type == type) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer type: %d is already used in layer: %d\n",
					__FUNCTION__, type, layer->id);
			return 0;
		}
		vbucket = vbucket->next;
	}

	if (v_hash_array_count_items(&node->layers) > MAX_LAYERS_COUNT) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() max number of layers in node: %d was reached\n",
				node->id);
		return 0;
	}

	layer = vs_layer_create(node, parent_layer, data_type, count, type);

	/* Try to find first free id for layer */
	/* TODO: this could be more effective */
	layer->id = node->last_layer_id;
	while( v_hash_array_find_item(&node->layers, layer) != NULL ) {
		layer->id++;

		if(layer->id > LAST_LAYER_ID) {
			layer->id = FIRST_LAYER_ID;
		}
	}
	node->last_layer_id = layer->id;

	/* Try to add new Tag to the hashed linked list of tags */
	vbucket = v_hash_array_add_item(&node->layers, (void*)layer, sizeof(struct VSLayer));

	if(vbucket==NULL) {
		free(layer);
		return 0;
	}

	layer->state = ENTITY_CREATING;

	/* Send layer_create to all node subscribers */
	node_subscriber = node->node_subs.first;
	while(node_subscriber != NULL) {
		vs_layer_send_create(node_subscriber, node, layer);
		node_subscriber = node_subscriber->next;
	}

	return 0;
}