Beispiel #1
0
char*
op_builtin_find(struct ccnl_relay_s *ccnl, struct configuration_s *config,
                int *restart, int *halt, char *prog, char *pending,
                struct stack_s **stack)
{
    int local_search = 0;
    struct stack_s *h;
    char *cp = NULL;
    struct ccnl_prefix_s *prefix;
    struct ccnl_content_s *c = NULL;

    if (*restart) {
        DEBUGMSG(DEBUG, "---to do: OP_FIND restart\n");
        *restart = 0;
        local_search = 1;
    } else {
        DEBUGMSG(DEBUG, "---to do: OP_FIND <%s> <%s>\n", prog+7, pending);
        h = pop_from_stack(&config->result_stack);
        //    if (h->type != STACK_TYPE_PREFIX)  ...
        config->fox_state->num_of_params = 1;
        config->fox_state->params = ccnl_malloc(sizeof(struct ccnl_stack_s *));
        config->fox_state->params[0] = h;
        config->fox_state->it_routable_param = 0;
    }
    prefix = config->fox_state->params[0]->content;

    //check if result is now available
    //loop by reentering (with local_search) after timeout of the interest...
    DEBUGMSG(DEBUG, "FIND: Checking if result was received\n");
    c = ccnl_nfn_local_content_search(ccnl, config, prefix);
    if (!c) {
        struct ccnl_prefix_s *copy;
        struct ccnl_interest_s *interest;
        if (local_search) {
            DEBUGMSG(INFO, "FIND: no content\n");
            return NULL;
        }
        //Result not in cache, search over the network
        //        struct ccnl_interest_s *interest = mkInterestObject(ccnl, config, prefix);
        copy = ccnl_prefix_dup(prefix);
        interest = ccnl_nfn_query2interest(ccnl, &copy, config);
        DEBUGMSG(DEBUG, "FIND: sending new interest from Face ID: %d\n",
                 interest->from->faceid);
        if (interest)
            ccnl_interest_propagate(ccnl, interest);
        //wait for content, return current program to continue later
        *halt = -1; //set halt to -1 for async computations
        return ccnl_strdup(prog);
    }

    DEBUGMSG(INFO, "FIND: result was found ---> handle it (%s), prog=%s, pending=%s\n", ccnl_prefix_to_path(prefix), prog, pending);
#ifdef USE_NACK
/*
    if (!strncmp((char*)c->content, ":NACK", 5)) {
        DEBUGMSG(DEBUG, "NACK RECEIVED, going to next parameter\n");
        ++config->fox_state->it_routable_param;
        
        return prog ? ccnl_strdup(prog) : NULL;
    }
*/
#endif
    prefix = ccnl_prefix_dup(prefix);
    push_to_stack(&config->result_stack, prefix, STACK_TYPE_PREFIX);

    if (pending) {
        DEBUGMSG(DEBUG, "Pending: %s\n", pending);

        cp = ccnl_strdup(pending);
    }
    return cp;
}
char*
ZAM_fox(struct ccnl_relay_s *ccnl, struct configuration_s *config,
        int *restart, int *halt, char *prog, char *arg, char *contd)
{
    int local_search = 0, i;
    int parameter_number = 0;
    struct ccnl_content_s *c = NULL;
    struct ccnl_prefix_s *pref;
    struct ccnl_interest_s *interest;

    DEBUGMSG(DEBUG, "---to do: FOX <%s>\n", arg);
    ccnl_free(arg);
    if (*restart) {
        *restart = 0;
        local_search = 1;
        goto recontinue;
    }

    {
        struct stack_s *h;
        h = pop_or_resolve_from_result_stack(ccnl, config);
        assert(h);
        //TODO CHECK IF INT
        config->fox_state->num_of_params = *(int*)h->content;
        h->next = NULL;
        ccnl_nfn_freeStack(h);
    }
    DEBUGMSG(DEBUG, "NUM OF PARAMS: %d\n", config->fox_state->num_of_params);

    config->fox_state->params = ccnl_malloc(sizeof(struct ccnl_stack_s *) *
                                            config->fox_state->num_of_params);

    for (i = 0; i < config->fox_state->num_of_params; ++i) {
        //pop parameter from stack
        config->fox_state->params[i] = pop_from_stack(&config->result_stack);
        switch (config->fox_state->params[i]->type) {
        case STACK_TYPE_INT:
            DEBUGMSG(DEBUG, "  info: Parameter %d %d\n", i,
                     *(int *)config->fox_state->params[i]->content);
            break;
        case STACK_TYPE_PREFIX:
            DEBUGMSG(DEBUG, "  info: Parameter %d %s\n", i,
                     ccnl_prefix_to_path((struct ccnl_prefix_s*)
                                      config->fox_state->params[i]->content));
            break;
        default:
            break;
        }
    }
    //as long as there is a routable parameter: try to find a result
    config->fox_state->it_routable_param = 0;

    //check if last result is now available
recontinue: //loop by reentering after timeout of the interest...
    if (local_search) {
        DEBUGMSG(DEBUG, "Checking if result was received\n");
        parameter_number = choose_parameter(config);
        pref = create_namecomps(ccnl, config, parameter_number,
                        config->fox_state->params[parameter_number]->content);
        // search for a result
        c = ccnl_nfn_local_content_search(ccnl, config, pref);
        set_propagate_of_interests_to_1(ccnl, pref);
        free_prefix(pref);
        //TODO Check? //TODO remove interest here?
        if (c) {
	    DEBUGMSG(DEBUG, "Result was found\n");
            DEBUGMSG_CFWD(INFO, "data after result was found %.*s\n", c->pkt->contlen, c->pkt->content);
            goto handlecontent;
	}
    }

    //result was not delivered --> choose next parameter
    ++config->fox_state->it_routable_param;
    parameter_number = choose_parameter(config);
    if (parameter_number < 0)
        //no more parameter --> no result found, can try a local computation
        goto local_compute;
    // create new prefix with name components!!!!
    pref = create_namecomps(ccnl, config, parameter_number,
                        config->fox_state->params[parameter_number]->content);
    c = ccnl_nfn_local_content_search(ccnl, config, pref);
    if (c) {
        free_prefix(pref);
        goto handlecontent;
    }

    // Result not in cache, search over the network
//    pref2 = ccnl_prefix_dup(pref);
    interest = ccnl_nfn_query2interest(ccnl, &pref, config);
    if (pref)
        free_prefix(pref);
    if (interest) {
        ccnl_interest_propagate(ccnl, interest);
        DEBUGMSG(DEBUG, "  new interest's face is %d\n", interest->from->faceid);
    }
    // wait for content, return current program to continue later
    *halt = -1; //set halt to -1 for async computations
    return ccnl_strdup(prog);

local_compute:
    if (config->local_done)
        return NULL;

    config->local_done = 1;
    pref = ccnl_nfnprefix_mkComputePrefix(config, config->suite);
    DEBUGMSG(DEBUG, "Prefix local computation: %s\n",
             ccnl_prefix_to_path(pref));
    interest = ccnl_nfn_query2interest(ccnl, &pref, config);
    if (pref)
        free_prefix(pref);
    if (interest)
        ccnl_interest_propagate(ccnl, interest);

handlecontent: //if result was found ---> handle it
    if (c) {
#ifdef USE_NACK
        if (!strncmp((char*)c->pkt->content, ":NACK", 5)) {
            DEBUGMSG(DEBUG, "NACK RECEIVED, going to next parameter\n");
            ++config->fox_state->it_routable_param;
            return prog ? ccnl_strdup(prog) : NULL;
        }
#endif
        int isANumber = 1, i = 0;
	    for(i = 0; i < c->pkt->contlen; ++i){
	    	if(!isdigit(c->pkt->content[i])){
                isANumber = 0;
                break;
            }
	    }
	    
        if (isANumber){
            int *integer = ccnl_malloc(sizeof(int));
            *integer = strtol((char*)c->pkt->content, 0, 0);
            push_to_stack(&config->result_stack, integer, STACK_TYPE_INT);
        } else {
            struct prefix_mapping_s *mapping;
            struct ccnl_prefix_s *name =
                create_prefix_for_content_on_result_stack(ccnl, config);
            push_to_stack(&config->result_stack, name, STACK_TYPE_PREFIX);
            mapping = ccnl_malloc(sizeof(struct prefix_mapping_s));
            mapping->key = ccnl_prefix_dup(name); //TODO COPY
            mapping->value = ccnl_prefix_dup(c->pkt->pfx);
            DBL_LINKED_LIST_ADD(config->fox_state->prefix_mapping, mapping);
            DEBUGMSG(DEBUG, "Created a mapping %s - %s\n",
                        ccnl_prefix_to_path(mapping->key),
                        ccnl_prefix_to_path(mapping->value));
        }
    }
    
    DEBUGMSG(DEBUG, " FOX continuation: %s\n", contd);
    return ccnl_strdup(contd);
}