root/src/add-ons/kernel/network/ppp/shared/libkernelppp/headers/KPPPInterface.h
/*
 * Copyright 2003-2006, Haiku Inc.
 * Distributed under the terms of the MIT License.
 */

#ifndef _K_PPP_INTERFACE__H
#define _K_PPP_INTERFACE__H

#include <driver_settings.h>

#ifndef _K_PPP_DEFS__H
#include <KPPPDefs.h>
#endif

#ifndef _PPP_CONTROL__H
#include <PPPControl.h>
#endif

#ifndef _K_PPP_LCP__H
#include <KPPPLCP.h>
#endif

#ifndef _K_PPP_REPORT_MANAGER__H
#include <KPPPReportManager.h>
#endif

#ifndef _K_PPP_STATE_MACHINE__H
#include <KPPPStateMachine.h>
#endif

#include <TemplateList.h>

#include <net_buffer.h>
#include <net_device.h>

#include <lock.h>
#include <util/AutoLock.h>

class KPPPDevice;
class KPPPProtocol;
class KPPPOptionHandler;

struct ppp_interface_module_info;
struct ppp_module_info;
struct ppp_interface_entry;


class KPPPInterface : public KPPPLayer {
                friend class PPPManager;
                friend class KPPPStateMachine;

        private:
                //!     Copies are not allowed.
                KPPPInterface(const KPPPInterface& copy);
                KPPPInterface& operator= (const KPPPInterface& copy);
                
        public:
                // we should set to private after finishing test
                // only PPPManager may construct us!
                KPPPInterface(const char *name, ppp_interface_entry *entry,
                        ppp_interface_id ID, const driver_settings *settings,
                        KPPPInterface *parent = NULL);
                ~KPPPInterface();

        public:
                void Delete();
                
                virtual status_t InitCheck() const;
                
                //!     Returns this interface's unique identifier.
                ppp_interface_id ID() const
                        { return fID; }
                
                //!     Returns interface's settings.
                driver_settings* Settings() const
                        { return fSettings; }
                
                //!     Returns the KPPPStateMachine of this interface.
                KPPPStateMachine& StateMachine()
                        { return fStateMachine; }
                //!     Returns the KPPPLCP protocol of this interface.
                KPPPLCP& LCP()
                        { return fLCP; }
                
                //!     Returns the interfac's ifnet structure that is exported to the netstack.
                net_device *Ifnet() const
                        { return fIfnet; }
                
                const char *Username() const;
                const char *Password() const;
                
                //!     Delay in miliseconds between a connect retry.
                uint32 ConnectRetryDelay() const
                        { return fConnectRetryDelay; }
                //!     Delay in miliseconds to wait until reconnecting.
                uint32 ReconnectDelay() const
                        { return fReconnectDelay; }
                
                //! Time when connection was established successfully.
                bigtime_t ConnectedSince() const
                        { return fConnectedSince; }
                
                //!     Used for reporting that a packet was send/received (updates idle time).
                void UpdateIdleSince()
                        { fUpdateIdleSince = true; }
                //!     Returns the time in seconds when the last packet was received.
                uint32 IdleSince() const
                        { return fIdleSince; }
                //!     If no packets were received this number of seconds we will disconnect.
                uint32 DisconnectAfterIdleSince() const
                        { return fDisconnectAfterIdleSince; }
                
                bool SetMRU(uint32 MRU);
                //!     This is the smallest MRU that we and the peer have.
                uint32 MRU() const
                        { return fMRU; }
                //!     Sets interface's maximum transfer unit (will set ifnet value accordingly).
                bool SetInterfaceMTU(uint32 interfaceMTU)
                        { return SetMRU(interfaceMTU - fHeaderLength); }
                //!     This is the MRU including protocol overhead.
                uint32 InterfaceMTU() const
                        { return fInterfaceMTU; }
                //!     Includes the length of all device and encapsulator headers.
                uint32 PacketOverhead() const;
                
                virtual status_t Control(uint32 op, void *data, size_t length);
                
                bool SetDevice(KPPPDevice *device);
                //!     Returns interface's transport device.
                KPPPDevice *Device() const
                        { return fDevice; }
                
                bool AddProtocol(KPPPProtocol *protocol);
                bool RemoveProtocol(KPPPProtocol *protocol);
                int32 CountProtocols() const;
                KPPPProtocol *ProtocolAt(int32 index) const;
                //!     Returns first protocol in chain.
                KPPPProtocol *FirstProtocol() const
                        { return fFirstProtocol; }
                KPPPProtocol *ProtocolFor(uint16 protocolNumber,
                        KPPPProtocol *start = NULL) const;
                
                // multilink methods
                bool AddChild(KPPPInterface *child);
                bool RemoveChild(KPPPInterface *child);
                //!     Returns the number of child interfaces that this interface has.
                int32 CountChildren() const
                        { return fChildren.CountItems(); }
                KPPPInterface *ChildAt(int32 index) const;
                //!     Returns this interface's parent.
                KPPPInterface *Parent() const
                        { return fParent; }
                //!     Returns whether we are a multilink-interface.
                bool IsMultilink() const
                        { return fIsMultilink; }
                
                void SetAutoReconnect(bool autoReconnect = true);
                //!     Returns whether this interface reconnects automatically.
                bool DoesAutoReconnect() const
                        { return fAutoReconnect; }
                
                void SetConnectOnDemand(bool connectOnDemand = true);
                //!     Returns whether connect-on-demand (auto-connect) is enabled.
                bool DoesConnectOnDemand() const
                        { return fConnectOnDemand; }
                
                void SetAskBeforeConnecting(bool ask);
                //!     Returns whether the user is asked before establishing the connection.
                bool DoesAskBeforeConnecting() const
                        { return fAskBeforeConnecting; }
                
                //!     Clients are in \c PPP_CLIENT_MODE and servers are in \c PPP_SERVER_MODE.
                ppp_mode Mode() const
                        { return fMode; }
                //!     Current state of the state machine (see enum: \c ppp_state).
                ppp_state State() const
                        { return fStateMachine.State(); }
                //!     Current phase of the state machine (see enum: \c ppp_phase).
                ppp_phase Phase() const
                        { return fStateMachine.Phase(); }
                
                // Protocol-Field-Compression
                bool SetPFCOptions(uint8 pfcOptions);
                //!     PFC option flags as defined in enum: \c ppp_pfc_options.
                uint8 PFCOptions() const
                        { return fPFCOptions; }
                /*!     \brief Local PFC state
                        
                        Values defined in \c ppp_pfc_state. \n
                        The local PFC state says if we accepted a request from the peer
                        i.e.: we may use PFC in outgoing packets.
                */
                ppp_pfc_state LocalPFCState() const
                        { return fLocalPFCState; }
                /*!     \brief Peer PFC state
                        
                        Values defined in \c ppp_pfc_state. \n
                        The peer PFC state says if the peer accepted a request us
                        i.e.: the peer might send PFC-compressed packets to us
                */
                ppp_pfc_state PeerPFCState() const
                        { return fPeerPFCState; }
                //!     Shortcut for check if local state is \c PPP_PFC_ACCEPTED.
                bool UseLocalPFC() const
                        { return LocalPFCState() == PPP_PFC_ACCEPTED; }
                
                virtual bool Up();
                        // in server mode Up() listens for an incoming connection
                virtual bool Down();
                bool WaitForConnection();
                //!     Returns if the interface is connected.
                bool IsUp() const
                        { return Phase() == PPP_ESTABLISHED_PHASE; }
                
                //!     Returns interface's report manager.
                KPPPReportManager& ReportManager()
                        { return fReportManager; }
                //!     Shortcut to KPPPReportManager::Report() of this interface's report manager.
                bool Report(ppp_report_type type, int32 code, void *data, int32 length)
                        { return ReportManager().Report(type, code, data, length); }
                        // returns false if reply was bad (or an error occured)
                
                bool LoadModules(driver_settings *settings,
                        int32 start, int32 count);
                bool LoadModule(const char *name, driver_parameter *parameter,
                        ppp_module_key_type type);
                
                virtual bool IsAllowedToSend() const;
                        // always returns true
                
                virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
                        // sends the packet to the next handler (normally the device)
                virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
                
                status_t ReceiveFromDevice(net_buffer *packet);
                        // This must not block KPPPDevice::Send()!
                
                void Pulse();
                        // this manages all timeouts, etc.

        private:
                bool RegisterInterface();
                        // adds us to the manager module and
                        // saves the returned ifnet structure
                bool UnregisterInterface();
                
                status_t StackControl(uint32 op, void *data);
                        // stack routes ioctls to interface
                status_t StackControlEachHandler(uint32 op, void *data);
                        // this calls StackControl() with the given parameters for each handler
                
                void CalculateInterfaceMTU();
                void CalculateBaudRate();
                
                void Reconnect(uint32 delay);
                
                // multilink methods
                //!     Set the parent of this interface.
                void SetParent(KPPPInterface *parent)
                        { fParent = parent; }

        private:
                ppp_interface_id fID;
                        // the manager assigns an ID to every interface
                driver_settings *fSettings;
                net_device *fIfnet;
                
                char *fUsername, *fPassword;
                
                thread_id fReconnectThread;
                uint32 fConnectAttempt, fConnectRetriesLimit;
                uint32 fConnectRetryDelay, fReconnectDelay;
                
                ppp_interface_module_info *fManager;
                
                ppp_statistics fStatistics;
                bigtime_t fConnectedSince;
                uint32 fIdleSince, fDisconnectAfterIdleSince;
                bool fUpdateIdleSince;
                uint32 fMRU, fInterfaceMTU, fHeaderLength;
                
                KPPPInterface *fParent;
                TemplateList<KPPPInterface*> fChildren;
                bool fIsMultilink;
                
                bool fAutoReconnect, fConnectOnDemand, fAskBeforeConnecting;
                
                ppp_mode fMode;
                ppp_pfc_state fLocalPFCState, fPeerPFCState;
                uint8 fPFCOptions;
                
                KPPPDevice *fDevice;
                KPPPProtocol *fFirstProtocol;
                TemplateList<char*> fModules;
                
                KPPPStateMachine fStateMachine;
                KPPPLCP fLCP;
                KPPPReportManager fReportManager;
                mutex& fLock;
                int32 fDeleteCounter;
};


#endif