/* * Add DAMA slave timeout timer to timer list. * Unlike the connection based timers the timeout function gets * triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT * (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in * 1/10th of a second.
*/
case AX25_STATE_0: case AX25_STATE_2: /* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */ if (!sk || sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN &&
sock_flag(sk, SOCK_DEAD))) { if (sk) {
sock_hold(sk);
ax25_destroy_socket(ax25);
bh_unlock_sock(sk); /* Ungrab socket and destroy it */
sock_put(sk);
} else
ax25_destroy_socket(ax25); return;
} break;
case AX25_STATE_3: /* * Check the state of the receive buffer.
*/ if (sk != NULL) { if (atomic_read(&sk->sk_rmem_alloc) <
(sk->sk_rcvbuf >> 1) &&
(ax25->condition & AX25_COND_OWN_RX_BUSY)) {
ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
ax25->condition &= ~AX25_COND_ACK_PENDING; break;
}
} break;
}
if (sk)
bh_unlock_sock(sk);
ax25_start_heartbeat(ax25);
}
/* dl1bke 960114: T3 works much like the IDLE timeout, but * gets reloaded with every frame for this * connection.
*/ void ax25_ds_t3timer_expiry(ax25_cb *ax25)
{
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
ax25_dama_off(ax25);
ax25_disconnect(ax25, ETIMEDOUT);
}
/* dl1bke 960228: close the connection when IDLE expires. * unlike T3 this timer gets reloaded only on * I frames.
*/ void ax25_ds_idletimer_expiry(ax25_cb *ax25)
{
ax25_clear_queues(ax25);
/* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC * within the poll of any connected channel. Remember * that we are not allowed to send anything unless we * get polled by the Master. * * Thus we'll have to do parts of our T1 handling in * ax25_enquiry_response().
*/ void ax25_ds_t1_timeout(ax25_cb *ax25)
{ switch (ax25->state) { case AX25_STATE_1: if (ax25->n2count == ax25->n2) { if (ax25->modulus == AX25_MODULUS) {
ax25_disconnect(ax25, ETIMEDOUT); return;
} else {
ax25->modulus = AX25_MODULUS;
ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
ax25->n2count = 0;
ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
}
} else {
ax25->n2count++; if (ax25->modulus == AX25_MODULUS)
ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND); else
ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
} break;
case AX25_STATE_2: if (ax25->n2count == ax25->n2) {
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND); if (!sock_flag(ax25->sk, SOCK_DESTROY))
ax25_disconnect(ax25, ETIMEDOUT); return;
} else {
ax25->n2count++;
} break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.