Exemplo n.º 1
0
/*
 *	Process an incoming LAPB frame
 */
void lapb_data_input(lapb_cb *lapb, struct sk_buff *skb)
{
    struct lapb_frame frame;

    lapb_decode(lapb, skb, &frame);

    switch (lapb->state) {
    case LAPB_STATE_0:
        lapb_state0_machine(lapb, skb, &frame);
        break;
    case LAPB_STATE_1:
        lapb_state1_machine(lapb, skb, &frame);
        break;
    case LAPB_STATE_2:
        lapb_state2_machine(lapb, skb, &frame);
        break;
    case LAPB_STATE_3:
        lapb_state3_machine(lapb, skb, &frame);
        break;
    case LAPB_STATE_4:
        lapb_state4_machine(lapb, skb, &frame);
        break;
    }

    lapb_kick(lapb);
}
Exemplo n.º 2
0
int lapb_data_request(void *token, struct sk_buff *skb)
{
	lapb_cb *lapb;

	if ((lapb = lapb_tokentostruct(token)) == NULL)
		return LAPB_BADTOKEN;

	if (lapb->state != LAPB_STATE_3 && lapb->state != LAPB_STATE_4)
		return LAPB_NOTCONNECTED;

	skb_queue_tail(&lapb->write_queue, skb);

	lapb_kick(lapb);

	return LAPB_OK;
}
Exemplo n.º 3
0
void lapb_t201timer_expiry(void * lapb_ptr) {
	struct lapb_cs *lapb = lapb_ptr;
	if (!lapb) return;

	struct lapb_cs_internal * lapb_int = lapb_get_internal(lapb);

	lapb_int->RC++;
	lapb->callbacks->debug(3, "[LAPB] S%d Timer_201 expired(%d of %d)",
						   lapb_int->state, lapb_int->RC, lapb->N201);
	switch (lapb_int->state) {
		/*
		 *	If we are a DCE, keep going DM .. DM .. DM
		 */
		case LAPB_STATE_0:
			if (lapb_is_dce(lapb)) {
				lapb_int->RC = 0;
				lapb->callbacks->debug(2, "[LAPB] S0 TX DM(0)");
				lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
			};
			break;

		/*
		 *	Awaiting connection state, send SABM(E), up to N2 times.
		 */
		case LAPB_STATE_1:
			if (lapb_int->RC >= lapb->N201) {
				lapb_stop_t201timer(lapb);
				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
				lapb_reset(lapb, LAPB_STATE_0);
			} else {
				if (lapb_is_extended(lapb)) {
					lapb->callbacks->debug(2, "[LAPB] S1 TX SABME(1)");
					lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
				} else {
					lapb->callbacks->debug(2, "[LAPB] S1 TX SABM(1)");
					lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
				};
			};
			break;

		/*
		 *	Awaiting disconnection state, send DISC, up to N2 times.
		 */
		case LAPB_STATE_2:
			if (lapb_int->RC >= lapb->N201) {
				lapb_stop_t201timer(lapb);
				lapb_requeue_frames(lapb);
				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
				lapb_reset(lapb, LAPB_STATE_0);
			} else {
				lapb->callbacks->debug(2, "[LAPB] S2 TX DISC(1)");
				lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
			};
			break;

		/*
		 *	Data transfer state, restransmit I frames, up to N2 times.
		 */
		case LAPB_STATE_3:
			lapb_requeue_frames(lapb);
			if (lapb_int->RC >= lapb->N201) {
				lapb_stop_t201timer(lapb);
				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
				lapb_reset(lapb, LAPB_STATE_0);
			} else {
				if (lapb_int->condition & LAPB_FRMR_CONDITION)
					lapb_transmit_frmr(lapb);
				else
					lapb_kick(lapb);
			};
			break;

		/*
		 *	Frame reject state, restransmit FRMR frames, up to N2 times.
		 */
		case LAPB_STATE_4:
			if (lapb_int->RC >= lapb->N201) {
				lapb_stop_t201timer(lapb);
				lapb_requeue_frames(lapb);
				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
				lapb_reset(lapb, LAPB_STATE_0);
			} else {
				lapb_transmit_frmr(lapb);
			};
			break;
	};
}