int delete_subscribe_katcp(struct katcp_dispatch *d, struct katcp_wit *w, unsigned int index) { struct katcp_subscribe *sub; sane_wit(w); if(index >= w->w_size){ #ifdef KATCP_CONSISTENCY_CHECKS fprintf(stderr, "delete subscribe: major logic problem, removed subscribe out of range\n"); abort(); #endif return -1; } sub = w->w_vector[index]; w->w_size--; if(index < w->w_size){ w->w_vector[index] = w->w_vector[w->w_size]; } destroy_subscribe_katcp(d, sub); return 0; }
static void destroy_wit_katcp(struct katcp_dispatch *d, struct katcp_wit *w) { unsigned int i; sane_wit(w); /* WARNING: TODO - send out device changed messages ? */ /* probably to everybody in group, not just subscribers ... */ for(i = 0; i < w->w_size; i++){ destroy_subscribe_katcp(d, w->w_vector[i]); w->w_vector[i] = NULL; } if(w->w_vector){ free(w->w_vector); } w->w_size = 0; if(w->w_endpoint){ release_endpoint_katcp(d, w->w_endpoint); w->w_endpoint = NULL; } w->w_magic = 0; free(w); }
int change_sensor_katcp(struct katcp_dispatch *d, void *state, char *name, struct katcp_vrbl *vx) { struct katcp_wit *w; struct katcl_parse *px; w = state; sane_wit(w); #ifdef DEBUG fprintf(stderr, "sensor: triggering sensor change logic on sensor %s\n", name); #endif if(vx->v_flags & KATCP_VRF_HID){ return 0; } px = make_sensor_katcp(d, name, vx, KATCP_SENSOR_STATUS_INFORM); if(px == NULL){ return -1; } broadcast_subscribe_katcp(d, w, px); destroy_parse_katcl(px); return 0; }
void dump_variable_sensor_katcp(struct katcp_dispatch *d, struct katcp_vrbl *vx, int level) { unsigned int i; struct katcp_wit *w; if(is_vrbl_sensor_katcp(d, vx) <= 0){ log_message_katcp(d, level, NULL, "variable at %p does not appear to be a reasonable sensor", vx); return; } if(vx->v_extra == NULL){ log_message_katcp(d, level, NULL, "no extra variable state found for %p", vx->v_extra); return; } w = vx->v_extra; sane_wit(w); for(i = 0; i < w->w_size; i++){ log_message_katcp(d, level, NULL, "subscriber[%u] uses strategy %d with endpoint %p", i, w->w_vector[i]->s_strategy, w->w_vector[i]->s_endpoint); if(w->w_vector[i]->s_variable != vx){ log_message_katcp(d, (w->w_vector[i]->s_variable == NULL) ? level : KATCP_LEVEL_FATAL, NULL, "subscriber[%u] variable mismatch: cached value %p does not match top-level %p", i, w->w_vector[i]->s_variable, vx); } } log_message_katcp(d, level, NULL, "variable %p has %u subscribers", vx, w->w_size); }
int delete_subscribe_katcp(struct katcp_dispatch *d, struct katcp_wit *w, unsigned int index) { /* WARNING: delete *has* to decrement size, otherwise the loop relying on it never terminates */ struct katcp_subscribe *sub; sane_wit(w); if(index >= w->w_size){ #ifdef KATCP_CONSISTENCY_CHECKS fprintf(stderr, "delete subscribe: major logic problem, removed subscribe out of range\n"); abort(); #endif return -1; } sub = w->w_vector[index]; w->w_size--; if(index < w->w_size){ w->w_vector[index] = w->w_vector[w->w_size]; } destroy_subscribe_katcp(d, sub); return 0; }
void release_endpoint_wit(struct katcp_dispatch *d, void *data) { struct katcp_wit *w; w = data; sane_wit(w); w->w_endpoint = NULL; }
void release_sensor_katcp(struct katcp_dispatch *d, void *state, char *name, struct katcp_vrbl *vx) { struct katcp_wit *w; if(state == NULL){ return; } w = state; sane_wit(w); destroy_wit_katcp(d, w); }
int find_subscribe_katcp(struct katcp_dispatch *d, struct katcp_wit *w, struct katcp_flat *fx) { int i; struct katcp_subscribe *sub; sane_wit(w); for(i = 0; i < w->w_size; i++){ sub = w->w_vector[i]; if(sub->s_endpoint == fx->f_peer){ return i; } } return -1; }
int broadcast_subscribe_katcp(struct katcp_dispatch *d, struct katcp_wit *w, struct katcl_parse *px) { unsigned int i, inc; struct katcp_subscribe *sub; sane_wit(w); #ifdef DEBUG fprintf(stderr, "sensor: broadcasting sensor update to %u interested parties\n", w->w_size); #endif i = 0; while(i < w->w_size){ sub = w->w_vector[i]; inc = 1; #ifdef KATCP_CONSISTENCY_CHECKS if(sub == NULL){ fprintf(stderr, "major logic problem: null entry at %u in vector of subscribers\n", i); abort(); } #endif /* WARNING: for events: should we check that something actually has changed ? */ if(sub->s_strategy == KATCP_STRATEGY_EVENT){ if(send_message_endpoint_katcp(d, w->w_endpoint, sub->s_endpoint, px, 0) < 0){ #if 0 log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "subscriber %u/%u unreachable at enpoint %p, retiring it", i, w->w_size, sub->s_endpoint); #endif /* other end could have gone away, notice it ... */ delete_subscribe_katcp(d, w, i); /* implies a w_size-- */ inc = 0; } #ifdef KATCP_CONSISTENCY_CHECKS } else { fprintf(stderr, "major logic problem: unimplemented sensor strategy %u\n", sub->s_strategy); abort(); #endif } i += inc; } return w->w_size; }
struct katcp_subscribe *create_subscribe_katcp(struct katcp_dispatch *d, struct katcp_wit *w, struct katcp_flat *fx) { struct katcp_subscribe *sub, **re; struct katcp_flat *tx; sane_wit(w); if(fx == NULL){ tx = this_flat_katcp(d); if(tx == NULL){ return NULL; } } else { tx = fx; } re = realloc(w->w_vector, sizeof(struct katcp_subscribe *) * (w->w_size + 1)); if(re == NULL){ return NULL; } w->w_vector = re; sub = malloc(sizeof(struct katcp_subscribe)); if(sub == NULL){ return NULL; } sub->s_variable = NULL; sub->s_endpoint = NULL; sub->s_strategy = KATCP_STRATEGY_OFF; /*********************/ reference_endpoint_katcp(d, tx->f_peer); sub->s_endpoint = tx->f_peer; w->w_vector[w->w_size] = sub; w->w_size++; return sub; }
int forget_event_variable_katcp(struct katcp_dispatch *d, struct katcp_vrbl *vx, struct katcp_flat *fx) { int index; struct katcp_wit *w; if(vx->v_extra == NULL){ return 1; } w = vx->v_extra; sane_wit(w); index = find_subscribe_katcp(d, w, fx); if(index < 0){ return 1; } return delete_subscribe_katcp(d, w, index); }
struct katcp_subscribe *locate_subscribe_katcp(struct katcp_dispatch *d, struct katcp_vrbl *vx, struct katcp_flat *fx) { int index; struct katcp_wit *w; if(vx->v_extra == NULL){ return NULL; } w = vx->v_extra; sane_wit(w); index = find_subscribe_katcp(d, w, fx); if(index < 0){ return NULL; } return w->w_vector[index]; }