/** * \brief This function handle taggroup_unsubscribe command */ int vs_handle_taggroup_unsubscribe(struct VS_CTX *vs_ctx, struct VSession *vsession, struct Generic_Cmd *taggroup_unsubscribe) { struct VSNode *node; struct VSTagGroup *tg; uint32 node_id = UINT32(taggroup_unsubscribe->data[0]); uint16 taggroup_id = UINT16(taggroup_unsubscribe->data[UINT32_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 ) { ret = 0; } else { /* 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); ret = 0; } else { ret = vs_taggroup_unsubscribe(tg, vsession); } } pthread_mutex_unlock(&node->mutex); return ret; }
/** * \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; }