示例#1
0
/**
 * \brief This function add session (client) to the list of clients that are
 * subscribed this node.
 */
static int vs_node_subscribe(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct VSNode *node,
		uint32 version)
{
	struct VSNode				*child_node;
	struct VSNodePermission		*perm;
	struct VSNodeSubscriber		*node_subscriber;
	struct VSLink				*link;
	struct VBucket				*bucket;
	struct VSTagGroup			*tg;
	struct VSLayer				*layer;
	int							user_can_read = 0;

	/* Can user subscribe to this node? */
	user_can_read = vs_node_can_read(vs_ctx, vsession, node);

	/* Add current session to the list of node subscribers */
	node_subscriber = (struct VSNodeSubscriber*)calloc(1, sizeof(struct VSNodeSubscriber));
	node_subscriber->session = vsession;
	node_subscriber->prio = VRS_DEFAULT_PRIORITY;
	v_list_add_tail(&node->node_subs, node_subscriber);

	/* TODO: send node_subscribe with version and commands with difference
	 * between this version and current state, when versing will be supported */
	if(version != 0) {
		v_print_log(VRS_PRINT_WARNING, "Version: %d != 0, versing is not supported yet\n", version);
	}

	/* Send node_perm commands to the new subscriber */
	perm = node->permissions.first;
	while(perm != NULL) {
		vs_node_send_perm(node_subscriber, node, perm->user, perm->permissions);
		perm = perm->next;
	}

	/* If the node is locked, then send node_lock to the subscriber */
	if(node->lock.session != NULL) {
		vs_node_send_lock(node_subscriber, node->lock.session, node);
	}

	/* If user doesn't have permission to subscribe to this node, then send
	 * only node_perm command explaining, why user can't rest of this
	 * node */
	if(user_can_read == 0) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Insufficient permission to read content of the node: %d\n", node->id);
		return 0;
	}

	/* Send node_create of all child nodes of this node and corresponding
	 * links */
	link = node->children_links.first;
	while(link!=NULL) {
		child_node = link->child;
		vs_node_send_create(node_subscriber, child_node, NULL);
		link = link->next;
	}

	/* Send taggroup_create of all tag_groups in this node */
	bucket = node->tag_groups.lb.first;
	while(bucket != NULL) {
		tg = (struct VSTagGroup*)bucket->data;
		if(tg->state == ENTITY_CREATING || tg->state == ENTITY_CREATED) {
			vs_taggroup_send_create(node_subscriber, node, tg);
		}
		bucket = bucket->next;
	}

	/* Send layer_create for all layers in this node */
	bucket = node->layers.lb.first;
	while(bucket != NULL) {
		layer = (struct VSLayer*)bucket->data;
		if(layer->state == ENTITY_CREATING || layer->state == ENTITY_CREATED) {
			vs_layer_send_create(node_subscriber, node, layer);
		}
		bucket = bucket->next;
	}

	return 1;
}
示例#2
0
/**
 * \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;
}