diff -dur gnokii.orig/common/gsm-statemachine.c gnokii/common/gsm-statemachine.c --- gnokii.orig/common/gsm-statemachine.c 2013-04-07 16:31:27.929885641 +0200 +++ gnokii/common/gsm-statemachine.c 2013-04-08 04:29:48.405936104 +0200 @@ -27,6 +27,9 @@ state->waiting_for_number = 0; state->received_number = 0; + state->keepalive.tv_sec = 0; + state->keepalive.tv_usec = 0; + return GN_ERR_NONE; } @@ -42,12 +45,29 @@ state->last_msg = message; state->current_state = GN_SM_MessageSent; - /* FIXME - clear KeepAlive timer */ + state->keepalive.tv_sec = 0; + state->keepalive.tv_usec = 0; + return state->link.send_message(messagesize, messagetype, message, state); } else return GN_ERR_NOTREADY; } +void sm_keepalive(struct gn_statemachine *state) +{ + gettimeofday(&(state->keepalive), NULL); +} + +int sm_is_alive(struct timeval *timeout, struct gn_statemachine *state) +{ + struct timeval t, now; + + timeradd(&(state->keepalive), timeout, &t); + gettimeofday(&now, NULL); + + return timercmp(&t, &now, >); +} + GNOKII_API gn_state gn_sm_loop(int timeout, struct gn_statemachine *state) { struct timeval loop_timeout; @@ -67,7 +87,8 @@ state->link.loop(&loop_timeout, state); } - /* FIXME - add calling a KeepAlive function here */ + sm_keepalive(state); + return state->current_state; } @@ -80,6 +101,9 @@ state->received_number = 0; if (state->link.reset) state->link.reset(state); + + state->keepalive.tv_sec = 0; + state->keepalive.tv_usec = 0; } } @@ -234,7 +258,8 @@ do { s = gn_sm_loop(1, state); /* Timeout=100ms */ gettimeofday(&now, NULL); - } while (timercmp(&next, &now, >) && (s == GN_SM_MessageSent)); + } while ((timercmp(&next, &now, >) || sm_is_alive(&timeout, state)) + && (s == GN_SM_MessageSent)); if (s == GN_SM_WaitingForResponse || s == GN_SM_ResponseReceived) break; if (state->config.sm_retry) { @@ -257,7 +282,8 @@ do { s = gn_sm_loop(1, state); /* Timeout=100ms */ gettimeofday(&now, NULL); - } while (timercmp(&next, &now, >) && (s != GN_SM_ResponseReceived)); + } while ((timercmp(&next, &now, >) || sm_is_alive(&timeout, state)) + && (s != GN_SM_ResponseReceived)); if (s == GN_SM_ResponseReceived) return sm_error_get(waitfor, state); diff -dur gnokii.orig/include/gnokii/statemachine.h gnokii/include/gnokii/statemachine.h --- gnokii.orig/include/gnokii/statemachine.h 2013-04-07 16:31:27.957885764 +0200 +++ gnokii/include/gnokii/statemachine.h 2013-04-08 04:26:38.220993018 +0200 @@ -79,6 +79,9 @@ union { gn_phonebook_entry pb_entry; } u; + + /* Store time of the last call to sm_keepalive() */ + struct timeval keepalive; }; GNOKII_API gn_state gn_sm_loop(int timeout, struct gn_statemachine *state);