int cli_set_ara_ack_mode(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [LINK, PASSIVE, NETWORK, DISABLED]", command); return CLI_ERROR; } switch(argv[0][0]) { case 'L': // TODO implement mode dessert_err("mode not yet implemented"); break; ara_ack_mode = ARA_ACK_LINK; break; case 'P': ara_ack_mode = ARA_ACK_PASSIVE; break; case 'N': ara_ack_mode = ARA_ACK_NETWORK; break; case 'D': ara_ack_mode = ARA_ACK_DISABLED; break; default: cli_print(cli, "invalid acknowledgement mode: %s", argv[0]); dessert_err("invalid acknowledgement mode: %s", argv[0]); return CLI_ERROR; } dessert_notice("ara_ack_mode set to %s", ara_ack_mode_strings[ara_ack_mode]); return CLI_OK; }
int cli_set_ara_forw_mode(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [BEST, WEIGHTED, RANDOM]", command); return CLI_ERROR; } switch(argv[0][0]) { case 'B': ara_forw_mode = ARA_FORW_B; break; case 'W': ara_forw_mode = ARA_FORW_W; break; case 'R': ara_forw_mode = ARA_FORW_R; break; default: cli_print(cli, "invalid forward mode: %s", argv[0]); dessert_err("invalid forward mode: %s", argv[0]); return CLI_ERROR; } dessert_notice("ara_forw_mode set to %s", ara_forw_mode_strings[ara_forw_mode]); return CLI_OK; }
int cli_set_max_missed_hello(struct cli_def* cli, char* command, char* argv[], int argc) { unsigned int tcoeff; if(argc != 1 || sscanf(argv[0], "%u", &tcoeff) != 1) { cli_print(cli, "usage of %s command [0, 1]\n", command); return CLI_ERROR_ARG; } if(max_missed_tc >= tcoeff) { max_missed_hello = (uint16_t) tcoeff; cli_print(cli, "set maximum number of tolerated missed HELLOs to %d", max_missed_hello); dessert_notice("set maximum number of tolerated missed HELLOs to %d", max_missed_hello); return CLI_OK; } cli_print(cli, "ERROR: max_missed_tc < max_missed_hello"); dessert_err("max_missed_tc < max_missed_hello"); return CLI_ERROR_ARG; }
int cli_set_ara_classify(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [on, off]", command); return CLI_ERROR; } if(!strcmp("on", argv[0])) { ara_classify = 1; } else if(!strcmp("off", argv[0])) { ara_classify = 0; } else { cli_print(cli, "invalid parameter: %s", argv[0]); dessert_err("invalid parameter: %s", argv[0]); return CLI_ERROR; } dessert_notice("path classification mode is %s", (ara_classify == 0) ? "disabled" : "enabled"); return CLI_OK; }
int cli_set_ara_backwards_inc(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [on, off]", command); return CLI_ERROR; } if(!strcmp("on", argv[0])) { ara_backwards_inc = 1; } else if(!strcmp("off", argv[0])) { ara_backwards_inc = 0; } else { cli_print(cli, "invalid parameter: %s", argv[0]); dessert_err("invalid parameter: %s", argv[0]); return CLI_ERROR; } dessert_notice("backwards pheromone trail increase is %s", (ara_backwards_inc == 0) ? "disabled" : "enabled"); return CLI_OK; }
int cli_set_ara_adap_evaporation(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [on, off]", command); return CLI_ERROR; } if(!strcmp("on", argv[0])) { ara_adap_evaporation = 1; } else if(!strcmp("off", argv[0])) { ara_adap_evaporation = 0; } else { cli_print(cli, "invalid parameter: %s", argv[0]); dessert_err("invalid parameter: %s", argv[0]); return CLI_ERROR; } dessert_notice("adaptive evaporation is %s", (ara_adap_evaporation == 0) ? "disabled" : "enabled"); return CLI_OK; }
int cli_set_ara_ptrail_mode(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [CLASSIC, CUBIC]", command); return CLI_ERROR; } if(!strcmp("CLASSIC", argv[0])) { ara_ptrail_mode = ARA_PTRAIL_CLASSIC; } else if(!strcmp("CUBIC", argv[0])) { ara_ptrail_mode = ARA_PTRAIL_CUBIC; } else if(!strcmp("LINEAR", argv[0])) { ara_ptrail_mode = ARA_PTRAIL_LINEAR; } else { cli_print(cli, "invalid pheromone trail mode: %s", argv[0]); dessert_err("invalid pheromone trail mode: %s", argv[0]); return CLI_ERROR; } dessert_notice("pheromone trail mode set to %s", ara_ptrail_mode_strings[ara_ptrail_mode]); return CLI_OK; }
int cli_set_rtprob_bants(struct cli_def* cli, const char* command, char* argv[], int argc) { if(argc != 1) { cli_print(cli, "usage %s [on, off]", command); return CLI_ERROR; } if(!strcmp("on", argv[0])) { ara_rtprob_bants = 1; } else if(!strcmp("off", argv[0])) { ara_rtprob_bants = 0; } else { cli_print(cli, "invalid parameter: %s", argv[0]); dessert_err("invalid parameter: %s", argv[0]); return CLI_ERROR; } ; dessert_notice("route problem BANTs have been %s", (ara_rtprob_bants == 0) ? "disabled" : "enabled"); return CLI_OK; }
/** trap an undeliverable packet (no next hop available) * * @arg dst destination with discovery waiting * @arg pkg packet to trap - pointer will simply be copied, so you MUST NOT free it * @returns count of packets now trapped for this dst, -1 if packet was discarded */ int trap_packet(ara_address_t dst, dessert_msg_t* pkg, size_t len, dessert_msg_proc_t* proc, dessert_frameid_t id) { ara_proc_t* ap = ara_proc_get(proc); packettrap_t* mytrap = NULL; trapped_packet_t* pkti = NULL; int i = 0; /* check if the packet has been trapped too often */ assert(proc != NULL); if(++(ap->trapcount) > ara_retry_max) { dessert_debug("discarding packet %d to " MAC " after %d times in trap", ap->seq, EXPLODE_ARRAY6(dst), ap->trapcount); return(-1); } else { dessert_debug("trapping packet %d to " MAC " for the %d. time", ap->seq, EXPLODE_ARRAY6(dst), ap->trapcount); } pthread_rwlock_wrlock(&traped_packets_lock); /* look up dst in hashtable - otherwise build list */ HASH_FIND(hh, traped_packets, dst, sizeof(dst), mytrap); /* no packets trapped yet - build trap... */ if(mytrap == NULL) { /* create the trap */ mytrap = malloc(sizeof(packettrap_t)); if(mytrap == NULL) { dessert_err("failed to allocate new hash table entry for packet trap"); goto trap_packet_out; } memcpy((mytrap->dst), dst, sizeof(ara_address_t)); mytrap->pkgs = malloc(ARA_TRAP_SLOTCHUNKSIZE * sizeof(trapped_packet_t)); if(mytrap->pkgs == NULL) { dessert_err("failed to allocate new hash table entry for packet trap"); free(mytrap); goto trap_packet_out; } mytrap->pkgs->pkg = NULL; mytrap->pkgs->len = 0; mytrap->pkgs->proc = NULL; mytrap->pkgs->id = 0; HASH_ADD_KEYPTR(hh, traped_packets, &(mytrap->dst), sizeof(dst), mytrap); } /* look for free slot */ i = 0; for(pkti = mytrap->pkgs; pkti->pkg != NULL; pkti++) { i++; } /* do we need to grow ? */ if(i % ARA_TRAP_SLOTCHUNKSIZE == ARA_TRAP_SLOTCHUNKSIZE - 1) { pkti = realloc(mytrap->pkgs, (i + ARA_TRAP_SLOTCHUNKSIZE + 1) * sizeof(trapped_packet_t)); if(pkti == NULL) { dessert_err("failed to modify hash table entry for packet trap"); goto trap_packet_out; } mytrap->pkgs = pkti; pkti += i; } /* copy/insert packet */ dessert_msg_clone(&(pkti->pkg), pkg, false); dessert_msg_proc_clone(&(pkti->proc), proc); pkti->len = len; pkti->id = id; /* fix list */ pkti++; i++; pkti->pkg = NULL; pkti->len = 0; pkti->proc = NULL; pkti->id = 0; /* done! */ trap_packet_out: pthread_rwlock_unlock(&traped_packets_lock); return(i); }
/** command "logging ringbuffer" */ int _dessert_cli_logging_ringbuffer(struct cli_def* cli, char* command, char* argv[], int argc) { int newlen = -1; if(argc != 1 || (newlen = (int) strtol(argv[0], NULL, 10)) < 0) { cli_print(cli, "usage %s [buffer length]\n", command); return CLI_ERROR; } if(newlen == _dessert_logrbuf_len) { return CLI_OK; } if(newlen == 0) { cli_print(cli, "will not set buffer length to 0 - use no logging ringbuffer instead\n"); return CLI_ERROR; } pthread_rwlock_wrlock(&_dessert_logrbuf_len_lock); /* make logging buffer larger - easy if not ENOMEM*/ if(newlen > _dessert_logrbuf_len) { _dessert_logrbuf = realloc(_dessert_logrbuf, newlen * DESSERT_LOGLINE_MAX * sizeof(char)); if(_dessert_logrbuf == NULL) { _dessert_logrbuf_len = 0; _dessert_logrbuf_cur = 0; } else { _dessert_logrbuf_len = newlen; } dessert_logcfg(DESSERT_LOG_RBUF); /* make logging buffer smaller - pain in the ass */ } else if(newlen < _dessert_logrbuf_len) { /* move current log buffer if needed */ if(_dessert_logrbuf_cur > newlen) { memmove(_dessert_logrbuf, _dessert_logrbuf + (DESSERT_LOGLINE_MAX *(_dessert_logrbuf_cur - newlen)), newlen * DESSERT_LOGLINE_MAX * sizeof(char)); _dessert_logrbuf_cur -= newlen; } _dessert_logrbuf = realloc(_dessert_logrbuf, newlen * DESSERT_LOGLINE_MAX * sizeof(char)); if(_dessert_logrbuf == NULL) { _dessert_logrbuf_len = 0; _dessert_logrbuf_cur = 0; } else { _dessert_logrbuf_len = newlen; } } else { dessert_err("this never happens"); } if(_dessert_logrbuf_used > _dessert_logrbuf_len - 1) { _dessert_logrbuf_used = _dessert_logrbuf_len - 1; } pthread_rwlock_unlock(&_dessert_logrbuf_len_lock); return CLI_OK; }
/** command "logging file" */ int _dessert_cli_logging_file(struct cli_def* cli, char* command, char* argv[], int argc) { FILE* newlogfd = NULL; #ifdef HAVE_LIBZ gzFile* newlogfdgz = NULL; const char gz[] = ".gz"; #endif if(argc != 1) { cli_print(cli, "usage %s filename\n", command); return CLI_ERROR; } #ifdef HAVE_LIBZ // see if the filename ends with ".gz" int len = strlen(argv[0]); int wrong_fext = strcmp(gz, argv[0] + len + 1 - sizeof(gz)); /* enable compression if the deamon author set the corresponding flag or the filename ends on ".gz" */ if((_dessert_logflags & _DESSERT_LOGFLAG_GZ) || !wrong_fext) { if(wrong_fext) { char newname[len+sizeof(gz)+1]; snprintf(newname, len + sizeof(gz) + 1, "%s%s", argv[0], gz); newlogfdgz = gzopen(newname, "a"); } else { newlogfdgz = gzopen(argv[0], "a"); } } else #endif { newlogfd = fopen(argv[0], "a"); } if(newlogfd == NULL #ifdef HAVE_LIBZ && newlogfdgz == NULL #endif ) { dessert_err("failed to open %s as logfile", argv[0]); cli_print(cli, "failed to open %s as logfile", argv[0]); return CLI_ERROR; } /* clean up old logfile first */ if(_dessert_logfd != NULL) { dessert_logcfg(DESSERT_LOG_NOFILE); fclose(_dessert_logfd); } #ifdef HAVE_LIBZ if(_dessert_logfdgz != NULL) { dessert_logcfg(DESSERT_LOG_NOFILE); gzclose(_dessert_logfdgz); } #endif if(newlogfd) { _dessert_logfd = newlogfd; dessert_logcfg(DESSERT_LOG_FILE | DESSERT_LOG_NOGZ); } #ifdef HAVE_LIBZ if(newlogfdgz) { _dessert_logfdgz = newlogfdgz; dessert_logcfg(DESSERT_LOG_FILE | DESSERT_LOG_GZ); } #endif return CLI_OK; }