Finished Up().
Redial needs one additional case to be complete. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4310 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -128,6 +128,8 @@ class PPPInterface {
|
|||||||
|
|
||||||
void CalculateMRU();
|
void CalculateMRU();
|
||||||
|
|
||||||
|
void Redial();
|
||||||
|
|
||||||
// multilink methods
|
// multilink methods
|
||||||
void SetParent(PPPInterface *parent)
|
void SetParent(PPPInterface *parent)
|
||||||
{ fParent = parent; }
|
{ fParent = parent; }
|
||||||
@@ -139,9 +141,8 @@ class PPPInterface {
|
|||||||
PPPReportManager fReportManager;
|
PPPReportManager fReportManager;
|
||||||
ifnet *fIfnet;
|
ifnet *fIfnet;
|
||||||
|
|
||||||
thread_id fUpThread;
|
thread_id fUpThread, fRedialThread;
|
||||||
uint32 fRetry;
|
uint32 fDialRetry, fDialRetriesLimit;
|
||||||
int32 fMaxRetries;
|
|
||||||
|
|
||||||
ppp_manager_info *fManager;
|
ppp_manager_info *fManager;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "settings_tools.h"
|
#include "settings_tools.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <new.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
@@ -23,12 +24,22 @@
|
|||||||
// - maybe some protocols must go down instead of being reset -> add flag for this
|
// - maybe some protocols must go down instead of being reset -> add flag for this
|
||||||
|
|
||||||
|
|
||||||
|
// needed for redial:
|
||||||
|
typedef struct redial_info {
|
||||||
|
PPPInterface *interface;
|
||||||
|
thread_id *thread;
|
||||||
|
} redial_info;
|
||||||
|
|
||||||
|
status_t redial_func(void *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NULL)
|
PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NULL)
|
||||||
: fSettings(dup_driver_settings(settings)),
|
: fSettings(dup_driver_settings(settings)),
|
||||||
fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()),
|
fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()),
|
||||||
fIfnet(NULL), fUpThread(-1), fRetry(0), fMaxRetries(0), fLinkMTU(1500),
|
fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0),
|
||||||
fAccessing(0), fChildrenCount(0), fDevice(NULL), fFirstEncapsulator(NULL),
|
fDialRetriesLimit(0), fLinkMTU(1500), fAccessing(0), fChildrenCount(0),
|
||||||
fLock(StateMachine().Locker())
|
fDevice(NULL), fFirstEncapsulator(NULL), fLock(StateMachine().Locker())
|
||||||
{
|
{
|
||||||
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
|
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
|
||||||
fManager = NULL;
|
fManager = NULL;
|
||||||
@@ -80,6 +91,7 @@ PPPInterface::~PPPInterface()
|
|||||||
// tell all listeners that we are being destroyed
|
// tell all listeners that we are being destroyed
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
// kill (or wait for) fRedialThread
|
||||||
// remove our iface, so that nobody will access it:
|
// remove our iface, so that nobody will access it:
|
||||||
// go down if up
|
// go down if up
|
||||||
// unregister from ppp_manager
|
// unregister from ppp_manager
|
||||||
@@ -345,7 +357,7 @@ PPPInterface::EncapsulatorFor(uint16 protocol,
|
|||||||
bool
|
bool
|
||||||
PPPInterface::AddChild(PPPInterface *child)
|
PPPInterface::AddChild(PPPInterface *child)
|
||||||
{
|
{
|
||||||
if(!child || child->Mode() != Mode())
|
if(!child)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
@@ -355,8 +367,6 @@ PPPInterface::AddChild(PPPInterface *child)
|
|||||||
|
|
||||||
child->SetParent(this);
|
child->SetParent(this);
|
||||||
|
|
||||||
CalculateMRU();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,18 +443,18 @@ PPPInterface::Up()
|
|||||||
fReportManager.EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
|
fReportManager.EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
|
||||||
fLock.Unlock();
|
fLock.Unlock();
|
||||||
|
|
||||||
if(me != fUpThread) {
|
// fUpThread tells the state machine to go up
|
||||||
// I am an observer
|
if(me == fUpThread)
|
||||||
|
StateMachine().OpenEvent();
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if(IsUp()) {
|
if(IsUp()) {
|
||||||
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE) {
|
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
|
||||||
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
continue;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsUp()) {
|
if(IsUp()) {
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
@@ -452,9 +462,14 @@ PPPInterface::Up()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(report.type != PPP_CONNECTION_REPORT) {
|
|
||||||
|
if(report.type == PPP_DESTRUCTION_REPORT) {
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
|
return false;
|
||||||
|
} else if(report.type != PPP_CONNECTION_REPORT) {
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(report.code == PPP_REPORT_GOING_UP) {
|
if(report.code == PPP_REPORT_GOING_UP) {
|
||||||
@@ -470,10 +485,12 @@ PPPInterface::Up()
|
|||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
return false;
|
return false;
|
||||||
} else if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
|
}
|
||||||
// TODO:
|
|
||||||
// !!! check code (after vacation you sometimes forget things ;) !!!
|
if(me != fUpThread) {
|
||||||
if(fRetry >= fMaxRetries || fUpThread == -1) {
|
// I am an observer
|
||||||
|
if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
|
||||||
|
if(fDialRetry >= fDialRetriesLimit || fUpThread == -1) {
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
return false;
|
return false;
|
||||||
@@ -482,8 +499,6 @@ PPPInterface::Up()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if(report.code == PPP_REPORT_CONNECTION_LOST) {
|
} else if(report.code == PPP_REPORT_CONNECTION_LOST) {
|
||||||
// TODO:
|
|
||||||
// !!! check code (after vacation you sometimes forget things ;) !!!
|
|
||||||
if(DoesAutoRedial()) {
|
if(DoesAutoRedial()) {
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
continue;
|
continue;
|
||||||
@@ -493,11 +508,37 @@ PPPInterface::Up()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// I am the thread for the real task
|
// I am the thread for the real task
|
||||||
while(true) {
|
if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
|
||||||
|
if(fDialRetry >= fDialRetriesLimit) {
|
||||||
|
fDialRetry = 0;
|
||||||
|
fUpThread = -1;
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
++fDialRetry;
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
|
StateMachine().OpenEvent();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if(report.code == PPP_REPORT_CONNECTION_LOST) {
|
||||||
|
// the state machine knows that we are going up and leaves
|
||||||
|
// the redial task to us
|
||||||
|
if(DoesAutoRedial() && fDialRetry < fDialRetriesLimit) {
|
||||||
|
++fDialRetry;
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
|
StateMachine().OpenEvent();
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
fDialRetry = 0;
|
||||||
|
fUpThread = -1;
|
||||||
|
PPP_REPLY(sender, B_OK);
|
||||||
|
fReportManager.DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,3 +967,31 @@ PPPInterface::CalculateMRU()
|
|||||||
if(Parent())
|
if(Parent())
|
||||||
Parent()->CalculateMRU();
|
Parent()->CalculateMRU();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PPPInterface::Redial()
|
||||||
|
{
|
||||||
|
if(fRedialThread != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// start a new thread that calls our Up() method
|
||||||
|
redial_info *info = new redial_info;
|
||||||
|
info.interface = this;
|
||||||
|
info.thread = &fRedialThread;
|
||||||
|
|
||||||
|
fRedialThread = spawn_thread(redial_func, "PPPInterface: redial_thread",
|
||||||
|
B_NORMAL_PRIORITY, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
redial_func(void *data)
|
||||||
|
{
|
||||||
|
redial_info *info = (redial_info*) data;
|
||||||
|
|
||||||
|
info->interface->Up();
|
||||||
|
*info->thread = -1;
|
||||||
|
|
||||||
|
delete info;
|
||||||
|
}
|
||||||
|
|||||||
@@ -427,15 +427,23 @@ PPPStateMachine::DownEvent()
|
|||||||
|
|
||||||
// maybe we need to redial
|
// maybe we need to redial
|
||||||
if(State() == PPP_STARTING_STATE) {
|
if(State() == PPP_STARTING_STATE) {
|
||||||
|
bool needsRedial = false;
|
||||||
|
|
||||||
if(fAuthentiactionStatus == PPP_AUTHENTICATION_FAILED
|
if(fAuthentiactionStatus == PPP_AUTHENTICATION_FAILED
|
||||||
|| fAuthenticationStatus == PPP_AUTHENTICATING
|
|| fAuthenticationStatus == PPP_AUTHENTICATING
|
||||||
|| fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
|| fPeerAuthenticationStatus == PPP_AUTHENTICATION_FAILED
|
||||||
|| fPeerAuthenticationStatus == PPP_AUTHENTICATING)
|
|| fPeerAuthenticationStatus == PPP_AUTHENTICATING)
|
||||||
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_FAILED,
|
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_AUTHENTICATION_FAILED,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
else
|
else {
|
||||||
|
// if we are going up and lost connection the redial attempt becomes
|
||||||
|
// a dial retry which is managed by the main thread in Interface::Up()
|
||||||
|
if(Interface()->fUpThread == -1)
|
||||||
|
needsRedial = true;
|
||||||
|
|
||||||
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
|
Interface()->Report(PPP_CONNECTION_REPORT, PPP_REPORT_CONNECTION_LOST,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(Interface()->Parent())
|
if(Interface()->Parent())
|
||||||
Interface()->Parent()->StateMachine().UpFailedEvent(Interface());
|
Interface()->Parent()->StateMachine().UpFailedEvent(Interface());
|
||||||
@@ -444,10 +452,9 @@ PPPStateMachine::DownEvent()
|
|||||||
|
|
||||||
if(Interface()->DoesAutoRedial()) {
|
if(Interface()->DoesAutoRedial()) {
|
||||||
// TODO:
|
// TODO:
|
||||||
// redial if we have been connected
|
// if we are reconfiguring we should redial, too
|
||||||
// problem: if we are reconfiguring we should redial, too
|
if(needsRedial)
|
||||||
// if(oldState == PPP_OPENED_STATE)
|
Interface()->Redial();
|
||||||
// Interface()->Redial();
|
|
||||||
} else if(!Interface()->DoesDialOnDemand())
|
} else if(!Interface()->DoesDialOnDemand())
|
||||||
Interface()->Delete();
|
Interface()->Delete();
|
||||||
} else {
|
} else {
|
||||||
@@ -481,6 +488,7 @@ PPPStateMachine::OpenEvent()
|
|||||||
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
if(Interface()->IsMultilink() && !Interface()->Parent()) {
|
||||||
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||||
for(int32 i = 0; i < Interface()->CountChildren(); i++)
|
for(int32 i = 0; i < Interface()->CountChildren(); i++)
|
||||||
|
if(Interface()->ChildAt(i)->Mode() == Interface()->Mode())
|
||||||
Interface()->ChildAt(i)->StateMachine().OpenEvent();
|
Interface()->ChildAt(i)->StateMachine().OpenEvent();
|
||||||
} else {
|
} else {
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
|
|||||||
Reference in New Issue
Block a user