static void command_unsubscribe(char * token, Channel * c) {
    char type[256];
    int err = 0;
    Subscription * s = NULL;
    LINK * l;

    json_read_string(&c->inp, type, sizeof(type));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            s = h;
            break;
        }
    }
    if (s == NULL) err = ERR_INV_CONTEXT;
    if (err == 0) delete_subscription(s);

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
static void command_subscribe(char * token, Channel * c) {
    char type[256];
    int err = 0;
    LINK * l;

    json_read_string(&c->inp, type, sizeof(type));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            err = ERR_OTHER;
            break;
        }
    }
    if (err == 0) {
        Subscription * s = loc_alloc_zero(sizeof(Subscription));
        list_init(&s->link_all);
        list_add_first(&s->link_all, &subscriptions);
        strncpy(s->type, type, sizeof(s->type) - 1);
        s->channel = c;
    }

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access,
        VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) {
    LINK * l;
    VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream));

    buf_len++;
    list_init(&stream->clients);
    strncpy(stream->type, type, sizeof(stream->type) - 1);
    stream->magic = STREAM_MAGIC;
    stream->id = id_cnt++;
    stream->access = access;
    stream->callback = callback;
    stream->callback_args = callback_args;
    stream->ref_cnt = 1;
    stream->buf = loc_alloc(buf_len);
    stream->buf_len = buf_len;
    for (l = subscriptions.next; l != &subscriptions; l = l->next) {
        Subscription * h = all2subscription(l);
        if (strcmp(type, h->type) == 0) {
            Trap trap;
            create_client(stream, h->channel);
            if (set_trap(&trap)) {
                send_event_stream_created(&h->channel->out, stream, context_id);
                clear_trap(&trap);
            }
            else {
                trace(LOG_ALWAYS, "Exception sending stream created event: %d %s",
                      trap.error, errno_to_str(trap.error));
            }
        }
    }
    list_add_first(&stream->link_all, &streams);
    *res = stream;
}
예제 #4
0
int virtual_stream_unsubscribe(Channel * c, const char * type) {
    LINK * l;
    int err = 0;
    Subscription * s = NULL;

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            s = h;
            break;
        }
    }
    if (s == NULL) err = ERR_INV_CONTEXT;
    if (err == 0) delete_subscription(s);
    else errno = err;

    return err == 0 ? 0 : -1;
}
static void channel_close_listener(Channel * c) {
    LINK * l = NULL;

    for (l = clients.next; l != &clients;) {
        StreamClient * client = all2client(l);
        l = l->next;
        if (client->channel == c) {
            trace(LOG_ALWAYS, "Stream is left connected by client: VS%d", client->stream->id);
            delete_client(client);
        }
    }

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c) {
            delete_subscription(h);
        }
    }
}
예제 #6
0
int virtual_stream_subscribe(Channel * c, const char * type) {
    LINK * l;
    int err = 0;

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            err = set_errno(ERR_OTHER, "Already subscribed");
            break;
        }
    }
    if (err == 0) {
        Subscription * s = (Subscription *)loc_alloc_zero(sizeof(Subscription));
        list_init(&s->link_all);
        list_add_first(&s->link_all, &subscriptions);
        strlcpy(s->type, type, sizeof(s->type));
        s->channel = c;
    }
    else errno = err;

    return err == 0 ? 0 : -1;
}