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, ©, 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); }