1/*
2 * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
4 */
5
6/*!	\class KPPPDevice
7	\brief Represents a device at the lowest level of the communcation stack.
8
9	A device may be, for example: Modem, PPPoE, PPTP. \n
10	It encapsulates the packet and sends it over a line to the other end.
11	The device is the first layer that receives a packet.
12*/
13
14#include <KPPPDevice.h>
15
16#include <net/if.h>
17
18#include <PPPControl.h>
19
20
21/*!	\brief Initializes the device.
22
23	\param name The device's type name (e.g.: PPPoE).
24	\param overhead Length of the header that is prepended to each packet.
25	\param interface Owning interface.
26	\param settings Device's settings.
27*/
28KPPPDevice::KPPPDevice(const char *name, uint32 overhead, KPPPInterface& interface,
29		driver_parameter *settings)
30	: KPPPLayer(name, PPP_DEVICE_LEVEL, overhead),
31	fMTU(1500),
32	fInterface(interface),
33	fSettings(settings),
34	fConnectionPhase(PPP_DOWN_PHASE)
35{
36}
37
38
39//!	Destructor. Removes device from interface.
40KPPPDevice::~KPPPDevice()
41{
42	if (Interface().Device() == this)
43		Interface().SetDevice(NULL);
44}
45
46
47/*!	\brief Allows private extensions.
48
49	If you override this method you must call the parent's method for unknown ops.
50*/
51status_t
52KPPPDevice::Control(uint32 op, void *data, size_t length)
53{
54	dprintf("KPPPDevice::Control\n");
55	switch (op) {
56		case PPPC_GET_DEVICE_INFO:
57		{
58			if (length < sizeof(ppp_device_info_t) || !data)
59				return B_NO_MEMORY;
60
61			ppp_device_info *info = (ppp_device_info*) data;
62			memset(info, 0, sizeof(ppp_device_info_t));
63			if (Name())
64				strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
65			info->MTU = MTU();
66			info->inputTransferRate = InputTransferRate();
67			info->outputTransferRate = OutputTransferRate();
68			info->outputBytesCount = CountOutputBytes();
69			info->isUp = IsUp();
70			break;
71		}
72
73		default:
74			return B_BAD_VALUE;
75	}
76
77	return B_OK;
78}
79
80
81//!	Returns \c true (indicates to KPPPInterface we are always allowed to send).
82bool
83KPPPDevice::IsAllowedToSend() const
84{
85	return true;
86		// our connection status will be reported in Send()
87}
88
89
90//!	This method is never used.
91status_t
92KPPPDevice::Receive(net_buffer *packet, uint16 protocolNumber)
93{
94	// let the interface handle the packet
95	if (protocolNumber == 0)
96		return Interface().ReceiveFromDevice(packet);
97	else
98		return Interface().Receive(packet, protocolNumber);
99}
100
101
102/*!	\brief Report that device is going up.
103
104	Called by Up(). \n
105	From now on, the connection attempt can may be aborted by calling Down().
106
107	\return
108		- \c true: You are allowed to connect.
109		- \c false: You should abort immediately. Down() will \e not be called!
110*/
111bool
112KPPPDevice::UpStarted()
113{
114	fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
115
116	return Interface().StateMachine().TLSNotify();
117}
118
119
120/*!	\brief Report that device is going down.
121
122	Called by Down().
123
124	\return
125		- \c true: You are allowed to disconnect.
126		- \c false: You must not disconnect!
127*/
128bool
129KPPPDevice::DownStarted()
130{
131	fConnectionPhase = PPP_TERMINATION_PHASE;
132
133	return Interface().StateMachine().TLFNotify();
134}
135
136
137//!	Reports that device failed going up. May only be called after Up() was called.
138void
139KPPPDevice::UpFailedEvent()
140{
141	fConnectionPhase = PPP_DOWN_PHASE;
142
143	Interface().StateMachine().UpFailedEvent();
144}
145
146
147//!	Reports that device went up. May only be called after Up() was called.
148void
149KPPPDevice::UpEvent()
150{
151	fConnectionPhase = PPP_ESTABLISHED_PHASE;
152
153	Interface().StateMachine().UpEvent();
154}
155
156
157//!	Reports that device went down. This may be called to indicate connection loss.
158void
159KPPPDevice::DownEvent()
160{
161	fConnectionPhase = PPP_DOWN_PHASE;
162
163	Interface().StateMachine().DownEvent();
164}
165