From: norly Date: Sun, 19 Mar 2017 00:44:33 +0000 (+0100) Subject: Detect limp home state X-Git-Url: https://git.enpas.org/?p=revag-nm.git;a=commitdiff_plain;h=619746cf21fadd0bddc675083c7899e88fbc0774 Detect limp home state --- diff --git a/vw-nm-tools.h b/vw-nm-tools.h index 44d5a1b..7d3c326 100644 --- a/vw-nm-tools.h +++ b/vw-nm-tools.h @@ -137,19 +137,38 @@ static void nm_reset(struct NM_Main *nm) { unsigned id; + if (nm->nodes[nm->my_id].next == nm->my_id) { + nm->lonely_resets++; + } + for (id = 0; id < nm->max_nodes; id++) { nm->nodes[id].next = 0xff; nm->nodes[id].state = NM_MAIN_OFF; } nm->nodes[nm->my_id].next = nm->my_id; - nm->nodes[nm->my_id].state = NM_MAIN_LOGIN; + if (nm->lonely_resets >= 5) { + printf("Limp home detected :(\n"); + + nm->nodes[nm->my_id].state = NM_MAIN_LIMPHOME; + nm_set_timer_limphome(nm); + } else { + nm->nodes[nm->my_id].state = NM_MAIN_LOGIN; + nm_set_timer_now(nm); + } +} + - nm_set_timer_now(nm); +static void nm_initreset(struct NM_Main *nm) +{ + nm_reset(nm); + + nm->lonely_resets = 0; } + static struct NM_Main* nm_alloc(unsigned node_bits, NM_ID my_id, canid_t can_base) { struct NM_Main *nm; @@ -173,7 +192,7 @@ static struct NM_Main* nm_alloc(unsigned node_bits, NM_ID my_id, canid_t can_bas nm->my_id = my_id; nm->can_base = can_base; - nm_reset(nm); + nm_initreset(nm); return nm; } diff --git a/vw-nm.c b/vw-nm.c index a181fce..16631ad 100644 --- a/vw-nm.c +++ b/vw-nm.c @@ -79,10 +79,10 @@ static void nm_handle_can_frame(struct NM_Main *nm, struct can_frame *frame) } /* If we're currently stuck in Limp Home mode, and we can see - * someone else's messages, reset and re-login. + * someone else's messages: reset counters, reset NM, re-login. */ if (nm->nodes[nm->my_id].state == NM_MAIN_LIMPHOME) { - nm_reset(nm); + nm_initreset(nm); return; } @@ -179,27 +179,36 @@ static void nm_buildframe(struct NM_Main *nm, struct can_frame *frame) static void nm_timeout_callback(struct NM_Main *nm, struct can_frame *frame) { - nm_buildframe(nm, frame); - switch(nm->timer_reason) { case NM_TIMER_NOW: /* We're due to log in */ + nm_buildframe(nm, frame); + + if ((nm->nodes[nm->my_id].state & NM_MAIN_MASK) + != NM_MAIN_LOGIN) { + + printf("BUG: TIMER_NOW expired in non-ON state %u\n", + nm->nodes[nm->my_id].state & NM_MAIN_MASK); + } /* We're going to be ready, let's * change state (RCD 310 behavior) */ nm->nodes[nm->my_id].state = NM_MAIN_ON; + nm_set_timer_normal(nm); break; case NM_TIMER_NORMAL: /* We're due to send our own ring message */ - switch(nm->nodes[nm->my_id].state & NM_MAIN_MASK) { - case NM_MAIN_ON: - break; - default: - printf("BUG: TIMER_NORMAL expired in non-ON state\n"); - break; + nm_buildframe(nm, frame); + + if ((nm->nodes[nm->my_id].state & NM_MAIN_MASK) + != NM_MAIN_ON) { + + printf("BUG: TIMER_NORMAL expired in non-ON state %u\n", + nm->nodes[nm->my_id].state & NM_MAIN_MASK); } + nm_set_timer_awol(nm); break; case NM_TIMER_AWOL: @@ -208,8 +217,12 @@ static void nm_timeout_callback(struct NM_Main *nm, struct can_frame *frame) * Reset everything and start over. */ nm_reset(nm); + nm_buildframe(nm, frame); break; case NM_TIMER_LIMPHOME: + printf("Limp home timer expired again :(\n"); + + nm_buildframe(nm, frame); nm_set_timer_limphome(nm); break; } diff --git a/vw-nm.h b/vw-nm.h index 23d0def..b9fd981 100644 --- a/vw-nm.h +++ b/vw-nm.h @@ -44,6 +44,9 @@ struct NM_Main { struct timeval tv; enum timer_reason timer_reason; + + /* How many times have we been alone when we reset? */ + int lonely_resets; };