* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Tromsø admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
}
}
-/*
- * Function irlap_next_state (self, state)
- *
- * Switches state and provides debug information
- *
- */
-static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
-{
- /*
- if (!self || self->magic != LAP_MAGIC)
- return;
-
- IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
- */
- self->state = state;
-}
-
/*
* Function irlap_state_ndm (event, skb, frame)
*
if (!self->discovery_log) {
IRDA_WARNING("%s: discovery log is gone! "
"maybe the discovery timeout has been set"
- " to short?\n", __FUNCTION__);
+ " too short?\n", __FUNCTION__);
break;
}
hashbin_insert(self->discovery_log,
} else {
/* Final packet of window */
irlap_send_data_primary_poll(self, skb);
- irlap_next_state(self, LAP_NRM_P);
/*
* Make sure state machine does not try to send
switch (event) {
case RECV_I_RSP: /* Optimize for the common case */
+ if (unlikely(skb->len <= LAP_ADDR_HEADER + LAP_CTRL_HEADER)) {
+ /*
+ * Input validation check: a stir4200/mcp2150
+ * combination sometimes results in an empty i:rsp.
+ * This makes no sense; we can just ignore the frame
+ * and send an rr:cmd immediately. This happens before
+ * changing nr or ns so triggers a retransmit
+ */
+ irlap_wait_min_turn_around(self, &self->qos_tx);
+ irlap_send_rr_frame(self, CMD_FRAME);
+ /* Keep state */
+ break;
+ }
/* FIXME: must check for remote_busy below */
#ifdef CONFIG_IRDA_FAST_RR
/*
*/
self->remote_busy = FALSE;
+ /* Stop final timer */
+ del_timer(&self->final_timer);
+
/*
* Nr as expected?
*/
ret = irlap_validate_nr_received(self, info->nr);
if (ret == NR_EXPECTED) {
- /* Stop final timer */
- del_timer(&self->final_timer);
-
/* Update Nr received */
irlap_update_nr_received(self, info->nr);
/* Resend rejected frames */
irlap_resend_rejected_frames(self, CMD_FRAME);
-
- /* Final timer ??? Jean II */
+ irlap_start_final_timer(self, self->final_timeout * 2);
irlap_next_state(self, LAP_NRM_P);
} else if (ret == NR_INVALID) {
IRDA_DEBUG(1, "%s(), Received RR with "
"invalid nr !\n", __FUNCTION__);
- del_timer(&self->final_timer);
irlap_next_state(self, LAP_RESET_WAIT);
/* N2 is the disconnect timer. Until we reach it, we retry */
if (self->retry_count < self->N2) {
- /* Retry sending the pf bit to the secondary */
- irlap_wait_min_turn_around(self, &self->qos_tx);
- irlap_send_rr_frame(self, CMD_FRAME);
+ if (skb_peek(&self->wx_list) == NULL) {
+ /* Retry sending the pf bit to the secondary */
+ IRDA_DEBUG(4, "nrm_p: resending rr");
+ irlap_wait_min_turn_around(self, &self->qos_tx);
+ irlap_send_rr_frame(self, CMD_FRAME);
+ } else {
+ IRDA_DEBUG(4, "nrm_p: resend frames");
+ irlap_resend_rejected_frames(self, CMD_FRAME);
+ }
irlap_start_final_timer(self, self->final_timeout);
self->retry_count++;