Example #1
0
File: vs_tag.c Project: verse/verse
/**
 * \brief This function tries to handle Tag_Destroy command
 */
int vs_handle_tag_destroy(struct VS_CTX *vs_ctx,
                          struct VSession *vsession,
                          struct Generic_Cmd *tag_destroy)
{
    struct VSNode			*node;
    struct VSTagGroup		*tg;
    struct VSTag			*tag;
    uint32 					node_id = UINT32(tag_destroy->data[0]);
    uint16 					taggroup_id = UINT16(tag_destroy->data[UINT32_SIZE]);
    uint16					tag_id = UINT16(tag_destroy->data[UINT32_SIZE + UINT16_SIZE]);
    int						ret = 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;
    }

    pthread_mutex_lock(&node->mutex);

    /* Node has to be created */
    if(vs_node_is_created(node) != 1) {
        goto end;
    }

    /* Is user owner of this node or can user write to this node? */
    if(vs_node_can_write(vsession, node) != 1) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s(): user: %s can't write to node: %d\n",
                    __FUNCTION__,
                    ((struct VSUser *)vsession->user)->username,
                    node->id);
        goto end;
    }

    /* Try to find TagGroup */
    if( (tg = vs_taggroup_find(node, taggroup_id)) == NULL) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() tag_group (id: %d) in node (id: %d) not found\n",
                    __FUNCTION__, taggroup_id, node_id);
        goto end;
    }

    /* Try to find Tag */
    if ( (tag = vs_tag_find(tg, tag_id)) == NULL) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() tag (id: %d) in tag_group (id: %d), node (id: %d) not found\n",
                    __FUNCTION__, tag_id, taggroup_id, node_id);
        goto end;
    }

    ret = vs_tag_send_destroy(node, tg, tag);

end:
    pthread_mutex_unlock(&node->mutex);

    return ret;
}
Example #2
0
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);
}
Example #3
0
/**
 * \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);
}
Example #4
0
/**
 * \brief This function handle changing link between nodes
 */
int vs_handle_link_change(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *node_link)
{
	struct VSUser			*user = (struct VSUser*)vsession->user;
	struct VSNode			*old_parent_node, *parent_node, *child_node;
	struct VSLink			*link;
	struct VSNodeSubscriber	*node_subscriber;
	struct VSEntityFollower *node_follower;
	uint32					parent_node_id = UINT32(node_link->data[0]);
	uint32					child_node_id = UINT32(node_link->data[UINT32_SIZE]);
	int						i;

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

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

	/* Is user owner of child node or can user write to child node? */
	if(vs_node_can_write(vsession, child_node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s():%d user: %s can't write to child node: %d (owner: %s)\n",
				__FUNCTION__, __LINE__, user->username, child_node->id,
				child_node->owner->username);
		return 0;
	}

	/* Old link */
	link = child_node->parent_link;

	/* Old parent node */
	old_parent_node = link->parent;

	/* Is user owner of old parent node or can user write to old parent node? */
	if(vs_node_can_write(vsession, old_parent_node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s():%d user: %s can't write to old parent node: %d (owner: %s)\n",
				__FUNCTION__, __LINE__, user->username, old_parent_node->id,
				old_parent_node->owner->username);
		return 0;
	}

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

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

	/* Test if client doesn't want to recreate existing link */
	if( parent_node == old_parent_node) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s():%d link between nodes (parent_id: %d) (child_id: %d) already exists\n",
				__FUNCTION__, __LINE__, parent_node->id, child_node->id);
		return 0;
	}

	/* Is user owner of parent node or can user write to parent node? */
	if(vs_node_can_write(vsession, parent_node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s():%d user: %s can't write to parent node: %d (owner: %s)\n",
				__FUNCTION__, __LINE__, user->username, parent_node->id,
				parent_node->owner->username);
		return 0;
	}

	/* Test, if new link could be created */
	if(vs_link_test_nodes(parent_node, child_node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s():%d node: %d can't be child of node: %d\n",
				__FUNCTION__, __LINE__, child_node->id, parent_node->id);
		return 0;
	}

	/* Remove link from old parent node */
	v_list_rem_item(&old_parent_node->children_links, link);

	/* Add link to new parent node */
	v_list_add_tail(&parent_node->children_links, link);
	link->parent = parent_node;

	/* Update child node internal properties according new parent node */
	vs_link_update_child(parent_node, child_node);

	/* Update version in child node, parent node and old parent node */
	vs_node_inc_version(parent_node);
	vs_node_inc_version(child_node);
	vs_node_inc_version(old_parent_node);

	/* Subscribers of old and new parent node will receive information about
	 * changing link between nodes. Prevent double sending command Node_Link,
	 * when clients are subscribed to both nodes. */

	/* Set temporary value in all sessions */
	for(i=0; i<vs_ctx->max_sessions; i++) {
		vs_ctx->vsessions[i]->tmp = 0;
	}

	/* Send Node_Link command to subscribers of old parent node and set
	 * session temporary value */
	node_subscriber = old_parent_node->node_subs.first;
	while(node_subscriber != NULL) {
		if(vs_node_can_read(node_subscriber->session, old_parent_node) == 1) {
			node_subscriber->session->tmp = 1;
			vs_link_change_send(node_subscriber, link);
		}
		node_subscriber = node_subscriber->next;
	}

	/* When client is subscribed to the new parent node and aware of child
	 * node, then send to the client only node_link */
	node_follower = child_node->node_folls.first;
	while(node_follower != NULL) {
		if(node_follower->node_sub->session->tmp != 1) {
			vs_link_change_send(node_follower->node_sub, link);
			node_follower->node_sub->session->tmp = 1;
		}
		node_follower = node_follower->next;
	}

	/* Send Node_Create command to subscribers of new parent node, when
	 * subscribers were not subscribed to child node */
	node_subscriber = parent_node->node_subs.first;
	while(node_subscriber != NULL) {
		if(node_subscriber->session->tmp != 1) {
			if(vs_node_can_read(node_subscriber->session, parent_node) == 1) {
				vs_node_send_create(node_subscriber, child_node, NULL);
			}
		}
		node_subscriber = node_subscriber->next;
	}

	return 1;
}
Example #5
0
/**
 * \brief This function tries to handle node_create command
 */
int vs_handle_taggroup_create(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *taggroup_create_cmd)
{
	struct VSNode			*node;
	struct VSTagGroup		*tg;
	struct VBucket			*vbucket;
	uint32 					node_id = UINT32(taggroup_create_cmd->data[0]);
	uint16 					taggroup_id = UINT16(taggroup_create_cmd->data[UINT32_SIZE]);
	uint16 					type = UINT16(taggroup_create_cmd->data[UINT32_SIZE+UINT16_SIZE]);
	int						ret = 0;

	/* Client has to send taggroup_create command with taggroup_id equal to
	 * the value 0xFFFF */
	if(taggroup_id != VRS_RESERVED_TAGGROUP_ID) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() taggroup_id: %d is not 0xFFFF\n",
				__FUNCTION__, taggroup_id);
		return 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;
	}

	pthread_mutex_lock(&node->mutex);

	/* Node has to be created */
	if( vs_node_is_created(node) != 1 ) {
		goto end;
	}

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

	/* Is user owner of this node or can user write to this node? */
	if(vs_node_can_write(vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"%s(): user: %s can't write to node: %d\n",
				__FUNCTION__,
				((struct VSUser *)vsession->user)->username,
				node->id);
		goto end;
	}

	/* Try to create new tag group */
	tg = vs_taggroup_create(node, VRS_RESERVED_TAGGROUP_ID, type);
	if(tg == NULL) {
		goto end;
	} else {
		struct VSNodeSubscriber *node_subscriber;

		/* Set state for this entity */
		tg->state = ENTITY_CREATING;

		ret = 1;

		/* Send tag group create command to all subscribers to the node
		 * that can read this node */
		for(node_subscriber = node->node_subs.first;
				node_subscriber != NULL;
				node_subscriber = node_subscriber->next)
		{
			if( vs_node_can_read(node_subscriber->session, node) == 1) {
				if(vs_taggroup_send_create(node_subscriber, node, tg) != 1) {
					ret = 0;
				}
			}
		}
	}

end:

	pthread_mutex_unlock(&node->mutex);

	return ret;
}
Example #6
0
File: vs_tag.c Project: verse/verse
/**
 * \brief This function tries to handle Tag_Set_Int8 command
 */
int vs_handle_tag_set(struct VS_CTX *vs_ctx,
                      struct VSession *vsession,
                      struct Generic_Cmd *tag_set,
                      uint8 data_type,
                      uint8 count)
{
    struct VSNode				*node;
    struct VSTagGroup			*tg;
    struct VSTag				*tag;
    struct VSEntitySubscriber	*tg_subscriber;
    uint32 						node_id;
    uint16 						taggroup_id;
    uint16						tag_id;
    int							ret = 0;

    node_id = UINT32(tag_set->data[0]);
    taggroup_id = UINT16(tag_set->data[UINT32_SIZE]);
    tag_id = UINT16(tag_set->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;
    }

    pthread_mutex_lock(&node->mutex);

    /* Node has to be created */
    if(vs_node_is_created(node) != 1) {
        goto end;
    }

    /* Is user owner of this node or can user write to this node? */
    if(vs_node_can_write(vsession, node) != 1) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s(): user: %s can't write to node: %d\n",
                    __FUNCTION__,
                    ((struct VSUser *)vsession->user)->username,
                    node->id);
        goto end;
    }

    /* Try to find TagGroup */
    if( (tg = vs_taggroup_find(node, taggroup_id)) == NULL) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() tag_group (id: %d) in node (id: %d) not found\n",
                    __FUNCTION__, taggroup_id, node_id);
        goto end;
    }

    /* Try to find Tag */
    if ( (tag = vs_tag_find(tg, tag_id)) == NULL) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() tag (id: %d) in tag_group (id: %d), node (id: %d) not found\n",
                    __FUNCTION__, tag_id, taggroup_id, node_id);
        goto end;
    }

    /* Data type has to match */
    if(data_type != tag->data_type) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() data type (%d) of tag (id: %d) in tg (id: %d) in node (id: %d) does not match data type of received command (%d)\n",
                    __FUNCTION__, tag->data_type, tag_id,
                    taggroup_id, node_id, data_type);
        goto end;
    }

    /* Count of values has to match */
    if(count != tag->count) {
        v_print_log(VRS_PRINT_DEBUG_MSG,
                    "%s() count of values (%d) of tag (id: %d) in tg (id: %d) in node (id: %d) does not match count of values of received command (%d)\n",
                    __FUNCTION__, tag->count, tag_id, taggroup_id, node_id, count);
        goto end;
    }

    /* Set value in tag */
    switch(tag->data_type) {
    case VRS_VALUE_TYPE_UINT8:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], UINT8_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_UINT16:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], UINT16_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_UINT32:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], UINT32_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_UINT64:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], UINT64_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_REAL16:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], REAL16_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_REAL32:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], REAL32_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_REAL64:
        memcpy(tag->value, &tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE], REAL64_SIZE*tag->count);
        break;
    case VRS_VALUE_TYPE_STRING8:
        if(tag->value == NULL) {
            tag->value = strdup(PTR(tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]));
        } else {
            size_t new_str_len = strlen(PTR(tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]));
            size_t old_str_len = strlen((char*)tag->value);
            /* Rewrite old string */
            if(new_str_len == old_str_len) {
                strcpy((char*)tag->value, PTR(tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]));
            } else {
                tag->value = (char*)realloc(tag->value, new_str_len*sizeof(char));
                strcpy((char*)tag->value, PTR(tag_set->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]));
            }
        }
        break;
    default:
        assert(0);
        break;
    }

    ret = 1;

    /* Set this tag as initialized, because value of this tag was set. */
    tag->flag = TAG_INITIALIZED;

    vs_taggroup_inc_version(tg);

    /* Send this tag to all client subscribed to the TagGroup */
    tg_subscriber = tg->tg_subs.first;
    while(tg_subscriber != NULL) {
        if(vs_tag_send_set(tg_subscriber->node_sub->session, tg_subscriber->node_sub->prio, node, tg, tag) != 1) {
            ret = 0;
        }
        tg_subscriber = tg_subscriber->next;
    }

end:
    pthread_mutex_unlock(&node->mutex);

    return ret;
}
Example #7
0
File: vs_tag.c Project: verse/verse
/**
 * \brief This function tries to handle Tag_Create command
 */
int vs_handle_tag_create(struct VS_CTX *vs_ctx,
                         struct VSession *vsession,
                         struct Generic_Cmd *tag_create)
{
    struct VSNode			*node;
    struct VSTagGroup		*tg;
    struct VSTag			*tag;
    struct VBucket			*vbucket;
    struct VSEntitySubscriber	*tg_subscriber;
    uint32 					node_id = UINT32(tag_create->data[0]);
    uint16 					taggroup_id = UINT16(tag_create->data[UINT32_SIZE]);
    uint16					tag_id = UINT16(tag_create->data[UINT32_SIZE + UINT16_SIZE]);
    uint8					data_type = UINT8(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]);
    uint8					count = UINT8(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE + UINT8_SIZE]);
    uint16 					type = UINT16(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE + UINT8_SIZE + UINT8_SIZE]);
    int						ret = 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;
    }

    pthread_mutex_lock(&node->mutex);

    /* Node has to be created */
    if(vs_node_is_created(node) != 1) {
        goto end;
    }

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

    /* Try to find TagGroup */
    if( (tg = vs_taggroup_find(node, taggroup_id)) == NULL) {
        v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_group (id: %d) in node (id: %d) not found\n",
                    __FUNCTION__, taggroup_id, node_id);
        goto end;
    }

    /* Tag Group has to be created too (it can't be in DELETING or DELETED state ) */
    if(!(tg->state == ENTITY_CREATED || tg->state == ENTITY_CREATING)) {
        v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag group (id: %d) from node (id: %d) is not in CREATING or CREATED state: %d\n",
                    __FUNCTION__, tg->id, node->id, tg->state);
        goto end;
    }

    /* Client has to send tag_create command with tag_id equal to
     * the value 0xFFFF */
    if(tag_id != RESERVED_TAG_ID) {
        v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_id: %d is not 0xFFFF\n",
                    __FUNCTION__, tag_id);
        goto end;
    }

    /* Is type of Tag supported? */
    if(!(data_type>VRS_VALUE_TYPE_RESERVED && data_type<=VRS_VALUE_TYPE_STRING8)) {
        v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_type: %d is not supported\n",
                    __FUNCTION__, data_type);
        goto end;
    }

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

    if (v_hash_array_count_items(&tg->tags) > MAX_TAGS_COUNT) {
        v_print_log(VRS_PRINT_DEBUG_MSG, "%s() max number of tags in node: %d tag_group: %d was reached\n",
                    tg->id);
        goto end;
    }

    /* Try to create new tag */
    tag = vs_tag_create(tg, RESERVED_TAG_ID, data_type, count, type);
    if(tag == NULL) {
        goto end;
    }

    ret = 1;

    tag->state = ENTITY_CREATING;

    /* Send TagCreate to all subscribers of tag group */
    tg_subscriber = tg->tg_subs.first;
    while(tg_subscriber != NULL) {
        if(vs_tag_send_create(tg_subscriber, node, tg, tag) != 1) {
            ret = 0;
        }
        tg_subscriber = tg_subscriber->next;
    }

end:
    pthread_mutex_unlock(&node->mutex);

    return ret;
}
Example #8
0
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;
}
Example #9
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;
}