Ejemplo n.º 1
0
/*
 * State machine for state 4, Awaiting Reset Confirmation State.
 * The handling of the timer(s) is in file x25_timer.c
 * Handling of state 0 and connection release is in af_x25.c.
 */
static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
	switch (frametype) {

		case X25_RESET_REQUEST:
			x25_write_internal(sk, X25_RESET_CONFIRMATION);
		case X25_RESET_CONFIRMATION: {
			struct x25_sock *x25 = x25_sk(sk);

			x25_stop_timer(sk);
			x25->condition = 0x00;
			x25->va        = 0;
			x25->vr        = 0;
			x25->vs        = 0;
			x25->vl        = 0;
			x25->state     = X25_STATE_3;
			x25_requeue_frames(sk);
			break;
		}
		case X25_CLEAR_REQUEST:
			x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
			x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
			break;

		default:
			break;
	}

	return 0;
}
Ejemplo n.º 2
0
void x25_enquiry_response(struct sock *sk)
{
	if (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)
		x25_write_internal(sk, X25_RNR);
	else
		x25_write_internal(sk, X25_RR);

	sk->protinfo.x25->vl         = sk->protinfo.x25->vr;
	sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;

	x25_stop_timer(sk);
}
Ejemplo n.º 3
0
void x25_enquiry_response(struct sock *sk)
{
	struct x25_opt *x25 = x25_sk(sk);

	if (x25->condition & X25_COND_OWN_RX_BUSY)
		x25_write_internal(sk, X25_RNR);
	else
		x25_write_internal(sk, X25_RR);

	x25->vl         = x25->vr;
	x25->condition &= ~X25_COND_ACK_PENDING;

	x25_stop_timer(sk);
}
/*
 *	Timer has expired, it may have been T2, T21, T22, or T23. We can tell
 *	by the state machine state.
 */
static inline void x25_do_timer_expiry(struct sock * sk)
{
	struct x25_opt *x25 = x25_sk(sk);

	switch (x25->state) {

		case X25_STATE_3:	/* T2 */
			if (x25->condition & X25_COND_ACK_PENDING) {
				x25->condition &= ~X25_COND_ACK_PENDING;
				x25_enquiry_response(sk);
			}
			break;

		case X25_STATE_1:	/* T21 */
		case X25_STATE_4:	/* T22 */
			x25_write_internal(sk, X25_CLEAR_REQUEST);
			x25->state = X25_STATE_2;
			x25_start_t23timer(sk);
			break;

		case X25_STATE_2:	/* T23 */
			x25_disconnect(sk, ETIMEDOUT, 0, 0);
			break;
	}
}
Ejemplo n.º 5
0
int x25_clear_request(struct x25_cs * x25) {
	if (!x25)
		return 0;

	struct x25_cs_internal * x25_int = x25_get_internal(x25);

	switch (x25_int->state) {
		case X25_STATE_0:
		case X25_STATE_2:
			x25_disconnect(x25, 0, 0, 0);
			break;

		case X25_STATE_1:
		case X25_STATE_3:
		case X25_STATE_4:
			x25_clear_queues(x25);
			x25->callbacks->debug(2, "[X25] S%d TX CLEAR_REQUEST", x25_int->state);
			_uchar old_state = x25_int->state;
			x25_int->state = X25_STATE_2;
			x25_write_internal(x25, X25_CLEAR_REQUEST);
			x25_start_timer(x25, &x25_int->ClearTimer);
			x25->callbacks->debug(1, "[X25] S%d -> S2", old_state);
			break;
	};

	return 0;
}
Ejemplo n.º 6
0
int x25_call_request(struct x25_cs * x25, struct x25_address *dest_addr) {
	int rc = X25_BADTOKEN;

	if (!x25)
		goto out;

	struct x25_cs_internal * x25_int = x25_get_internal(x25);

	rc = X25_NOTCONNECTED;
	if (x25_int->state == X25_STATE_1)
		goto out;

	rc = X25_CONNECTED;
	if (x25_int->state == X25_STATE_3)
		goto out;

	x25_limit_facilities(x25);

	x25->dest_addr = *dest_addr;

	x25->callbacks->debug(1, "[X25] S%d Make Call to %s", x25_int->state, dest_addr->x25_addr);
	x25->callbacks->debug(2, "[X25] S%d TX CALL_REQUEST", x25_int->state);
	x25->callbacks->debug(1, "[X25] S%d -> S1", x25_int->state);
	x25_int->state = X25_STATE_1;
	x25_write_internal(x25, X25_CALL_REQUEST);

	x25_start_timer(x25, &x25_int->CallTimer);

	rc = 0;
out:
	return rc;
}
Ejemplo n.º 7
0
/*
 * State machine for state 1, Awaiting Call Accepted State.
 * The handling of the timer(s) is in file x25_timer.c.
 * Handling of state 0 and connection release is in af_x25.c.
 */
static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
	struct x25_address source_addr, dest_addr;

	switch (frametype) {
		case X25_CALL_ACCEPTED: {
			struct x25_sock *x25 = x25_sk(sk);

			x25_stop_timer(sk);
			x25->condition = 0x00;
			x25->vs        = 0;
			x25->va        = 0;
			x25->vr        = 0;
			x25->vl        = 0;
			x25->state     = X25_STATE_3;
			sk->sk_state   = TCP_ESTABLISHED;
			/*
			 *	Parse the data in the frame.
			 */
			skb_pull(skb, X25_STD_MIN_LEN);
			skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
			skb_pull(skb,
				 x25_parse_facilities(skb, &x25->facilities,
						&x25->dte_facilities,
						&x25->vc_facil_mask));
			/*
			 *	Copy any Call User Data.
			 */
			if (skb->len >= 0) {
				memcpy(x25->calluserdata.cuddata, skb->data,
				       skb->len);
				x25->calluserdata.cudlength = skb->len;
			}
			if (!sock_flag(sk, SOCK_DEAD))
				sk->sk_state_change(sk);
			break;
		}
		case X25_CLEAR_REQUEST:
			x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
			x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
			break;

		default:
			break;
	}

	return 0;
}
Ejemplo n.º 8
0
/*
 * State machine for state 2, Awaiting Clear Confirmation State.
 * The handling of the timer(s) is in file x25_timer.c
 * Handling of state 0 and connection release is in af_x25.c.
 */
static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
	switch (frametype) {

		case X25_CLEAR_REQUEST:
			x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
			x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
			break;

		case X25_CLEAR_CONFIRMATION:
			x25_disconnect(sk, 0, 0, 0);
			break;

		default:
			break;
	}

	return 0;
}
Ejemplo n.º 9
0
int x25_pvc_setup(struct x25_cs * x25) {
	int rc = X25_BADTOKEN;

	if (!x25)
		goto out;

	struct x25_cs_internal * x25_int = x25_get_internal(x25);


	x25_limit_facilities(x25);


	x25->callbacks->debug(1, "[X25] S%d PVC setup", x25_int->state);
	x25->callbacks->debug(2, "[X25] S%d TX RESET_REQUEST", x25_int->state);
	x25->callbacks->debug(1, "[X25] S%d -> S4", x25_int->state);
	x25_int->state = X25_STATE_4;
	x25_write_internal(x25, X25_RESET_REQUEST);

	x25_start_timer(x25, &x25_int->ResetTimer);

	rc = 0;
out:
	return rc;
}
Ejemplo n.º 10
0
/*
 * State machine for state 3, Connected State.
 * The handling of the timer(s) is in file x25_timer.c
 * Handling of state 0 and connection release is in af_x25.c.
 */
static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype, int ns, int nr, int q, int d, int m)
{
	int queued = 0;
	int modulus;
	struct x25_sock *x25 = x25_sk(sk);

	modulus = (x25->neighbour->extended) ? X25_EMODULUS : X25_SMODULUS;

	switch (frametype) {

		case X25_RESET_REQUEST:
			x25_write_internal(sk, X25_RESET_CONFIRMATION);
			x25_stop_timer(sk);
			x25->condition = 0x00;
			x25->vs        = 0;
			x25->vr        = 0;
			x25->va        = 0;
			x25->vl        = 0;
			x25_requeue_frames(sk);
			break;

		case X25_CLEAR_REQUEST:
			x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
			x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
			break;

		case X25_RR:
		case X25_RNR:
			if (!x25_validate_nr(sk, nr)) {
				x25_clear_queues(sk);
				x25_write_internal(sk, X25_RESET_REQUEST);
				x25_start_t22timer(sk);
				x25->condition = 0x00;
				x25->vs        = 0;
				x25->vr        = 0;
				x25->va        = 0;
				x25->vl        = 0;
				x25->state     = X25_STATE_4;
			} else {
				x25_frames_acked(sk, nr);
				if (frametype == X25_RNR) {
					x25->condition |= X25_COND_PEER_RX_BUSY;
				} else {
					x25->condition &= ~X25_COND_PEER_RX_BUSY;
				}
			}
			break;

		case X25_DATA:	/* XXX */
			x25->condition &= ~X25_COND_PEER_RX_BUSY;
			if ((ns != x25->vr) || !x25_validate_nr(sk, nr)) {
				x25_clear_queues(sk);
				x25_write_internal(sk, X25_RESET_REQUEST);
				x25_start_t22timer(sk);
				x25->condition = 0x00;
				x25->vs        = 0;
				x25->vr        = 0;
				x25->va        = 0;
				x25->vl        = 0;
				x25->state     = X25_STATE_4;
				break;
			}
			x25_frames_acked(sk, nr);
			if (ns == x25->vr) {
				if (x25_queue_rx_frame(sk, skb, m) == 0) {
					x25->vr = (x25->vr + 1) % modulus;
					queued = 1;
				} else {
					/* Should never happen */
					x25_clear_queues(sk);
					x25_write_internal(sk, X25_RESET_REQUEST);
					x25_start_t22timer(sk);
					x25->condition = 0x00;
					x25->vs        = 0;
					x25->vr        = 0;
					x25->va        = 0;
					x25->vl        = 0;
					x25->state     = X25_STATE_4;
					break;
				}
				if (atomic_read(&sk->sk_rmem_alloc) >
				    (sk->sk_rcvbuf / 2))
					x25->condition |= X25_COND_OWN_RX_BUSY;
			}
			/*
			 *	If the window is full Ack it immediately, else
			 *	start the holdback timer.
			 */
			if (((x25->vl + x25->facilities.winsize_in) % modulus) == x25->vr) {
				x25->condition &= ~X25_COND_ACK_PENDING;
				x25_stop_timer(sk);
				x25_enquiry_response(sk);
			} else {
				x25->condition |= X25_COND_ACK_PENDING;
				x25_start_t2timer(sk);
			}
			break;

		case X25_INTERRUPT_CONFIRMATION:
			x25->intflag = 0;
			break;

		case X25_INTERRUPT:
			if (sock_flag(sk, SOCK_URGINLINE))
				queued = !sock_queue_rcv_skb(sk, skb);
			else {
				skb_set_owner_r(skb, sk);
				skb_queue_tail(&x25->interrupt_in_queue, skb);
				queued = 1;
			}
			sk_send_sigurg(sk);
			x25_write_internal(sk, X25_INTERRUPT_CONFIRMATION);
			break;

		default:
			printk(KERN_WARNING "x25: unknown %02X in state 3\n", frametype);
			break;
	}

	return queued;
}