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