summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2017-03-19 01:44:33 +0100
committernorly <ny-git@enpas.org>2017-03-19 01:46:11 +0100
commit619746cf21fadd0bddc675083c7899e88fbc0774 (patch)
treec7fd307098442a969e01cf810fff528cb2aab468
parent93a111710a794d7c602d2b31387e4f882df4a7cd (diff)
Detect limp home state
-rw-r--r--vw-nm-tools.h25
-rw-r--r--vw-nm.c33
-rw-r--r--vw-nm.h3
3 files changed, 48 insertions, 13 deletions
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;
};