1/*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "_KPPPPFCHandler.h"
7
8#include <KPPPConfigurePacket.h>
9
10
11static const uint8 kPFCType = 0x7;
12
13
14_KPPPPFCHandler::_KPPPPFCHandler(ppp_pfc_state& localPFCState,
15		ppp_pfc_state& peerPFCState, KPPPInterface& interface)
16	: KPPPOptionHandler("PFC Handler", kPFCType, interface, NULL),
17	fLocalPFCState(localPFCState),
18	fPeerPFCState(peerPFCState)
19{
20}
21
22
23status_t
24_KPPPPFCHandler::AddToRequest(KPPPConfigurePacket& request)
25{
26	// is PFC not requested or was it rejected?
27	if (fLocalPFCState == PPP_PFC_REJECTED
28			|| (Interface().PFCOptions() & PPP_REQUEST_PFC) == 0)
29		return B_OK;
30
31	// add PFC request
32	ppp_configure_item item;
33	item.type = kPFCType;
34	item.length = 2;
35	return request.AddItem(&item) ? B_OK : B_ERROR;
36}
37
38
39status_t
40_KPPPPFCHandler::ParseNak(const KPPPConfigurePacket& nak)
41{
42	// naks do not contain PFC items
43	if (nak.ItemWithType(kPFCType))
44		return B_ERROR;
45
46	return B_OK;
47}
48
49
50status_t
51_KPPPPFCHandler::ParseReject(const KPPPConfigurePacket& reject)
52{
53	if (reject.ItemWithType(kPFCType)) {
54		fLocalPFCState = PPP_PFC_REJECTED;
55
56		if (Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
57			return B_ERROR;
58	}
59
60	return B_OK;
61}
62
63
64status_t
65_KPPPPFCHandler::ParseAck(const KPPPConfigurePacket& ack)
66{
67	if (ack.ItemWithType(kPFCType))
68		fLocalPFCState = PPP_PFC_ACCEPTED;
69	else {
70		fLocalPFCState = PPP_PFC_DISABLED;
71
72		if (Interface().PFCOptions() & PPP_FORCE_PFC_REQUEST)
73			return B_ERROR;
74	}
75
76	return B_OK;
77}
78
79
80status_t
81_KPPPPFCHandler::ParseRequest(const KPPPConfigurePacket& request,
82	int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
83{
84	if (!request.ItemWithType(kPFCType))
85		return B_OK;
86
87	if ((Interface().PFCOptions() & PPP_ALLOW_PFC) == 0) {
88		ppp_configure_item item;
89		item.type = kPFCType;
90		item.length = 2;
91		return reject.AddItem(&item) ? B_OK : B_ERROR;
92	}
93
94	return B_OK;
95}
96
97
98status_t
99_KPPPPFCHandler::SendingAck(const KPPPConfigurePacket& ack)
100{
101	ppp_configure_item *item = ack.ItemWithType(kPFCType);
102
103	if (item && (Interface().PFCOptions() & PPP_ALLOW_PFC) == 0)
104		return B_ERROR;
105
106	if (item)
107		fPeerPFCState = PPP_PFC_ACCEPTED;
108	else
109		fPeerPFCState = PPP_PFC_DISABLED;
110
111	return B_OK;
112}
113
114
115void
116_KPPPPFCHandler::Reset()
117{
118	fLocalPFCState = fPeerPFCState = PPP_PFC_DISABLED;
119}
120