Rework initial auto joining and add big TODOs.
* If we have a configured network, then we always try to connect to it as soon as the interface has been brought up. * If we don't have a configured network and are auto configuring, we use the AutoconfigLooper to also do initial auto joins. * Before issuing auto joins we need to wait for scan results to come in, so we watch for corresponding messages. For now auto joining is a one shot attempt as the infrastructure to properly tell reasons for scans apart is not yet there.
This commit is contained in:
parent
e484cc5098
commit
a9abcc37cd
@ -19,6 +19,7 @@
|
||||
#define kMsgRemovePersistentNetwork 'RPnw'
|
||||
#define kMsgJoinNetwork 'JNnw'
|
||||
#define kMsgLeaveNetwork 'LVnw'
|
||||
#define kMsgAutoJoinNetwork 'AJnw'
|
||||
|
||||
|
||||
#endif // _NET_SERVER_H
|
||||
|
@ -33,7 +33,8 @@ AutoconfigLooper::AutoconfigLooper(BMessenger target, const char* device)
|
||||
fTarget(target),
|
||||
fDevice(device),
|
||||
fCurrentClient(NULL),
|
||||
fLastMediaStatus(0)
|
||||
fLastMediaStatus(0),
|
||||
fJoiningNetwork(false)
|
||||
{
|
||||
BMessage ready(kMsgReadyToRun);
|
||||
PostMessage(&ready);
|
||||
@ -124,7 +125,8 @@ AutoconfigLooper::_ConfigureIPv4()
|
||||
void
|
||||
AutoconfigLooper::_ReadyToRun()
|
||||
{
|
||||
start_watching_network(B_WATCH_NETWORK_LINK_CHANGES, this);
|
||||
start_watching_network(
|
||||
B_WATCH_NETWORK_LINK_CHANGES | B_WATCH_NETWORK_WLAN_CHANGES, this);
|
||||
|
||||
BNetworkInterface interface(fDevice.String());
|
||||
if (interface.HasLink()) {
|
||||
@ -139,22 +141,35 @@ AutoconfigLooper::_ReadyToRun()
|
||||
|
||||
|
||||
void
|
||||
AutoconfigLooper::MessageReceived(BMessage* message)
|
||||
AutoconfigLooper::_NetworkMonitorNotification(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgReadyToRun:
|
||||
_ReadyToRun();
|
||||
break;
|
||||
int32 opcode;
|
||||
BString device;
|
||||
if (message->FindString("device", &device) != B_OK) {
|
||||
if (message->FindString("interface", &device) != B_OK)
|
||||
return;
|
||||
|
||||
case B_NETWORK_MONITOR:
|
||||
const char* device;
|
||||
int32 opcode;
|
||||
// TODO: Clean this mess up. Wireless devices currently use their
|
||||
// "device_name" in the interface field. First of all the
|
||||
// joins/leaves/scans should be device, not interface specific, so
|
||||
// the field should be changed. Then the device_name as seen by the
|
||||
// driver is missing the "/dev" part, as it is a relative path within
|
||||
// "/dev". On the other hand the net stack uses names that include
|
||||
// "/dev" as it uses them to open the fds, hence a full absolute path.
|
||||
// Note that the wpa_supplicant does the same workaround as we do here
|
||||
// to build an interface name, so that has to be changed as well when
|
||||
// this is fixed.
|
||||
device.Prepend("/dev/");
|
||||
}
|
||||
|
||||
if (device != fDevice || message->FindInt32("opcode", &opcode) != B_OK)
|
||||
return;
|
||||
|
||||
switch (opcode) {
|
||||
case B_NETWORK_DEVICE_LINK_CHANGED:
|
||||
{
|
||||
int32 media;
|
||||
if (message->FindInt32("opcode", &opcode) != B_OK
|
||||
|| opcode != B_NETWORK_DEVICE_LINK_CHANGED
|
||||
|| message->FindString("device", &device) != B_OK
|
||||
|| fDevice != device
|
||||
|| message->FindInt32("media", &media) != B_OK)
|
||||
if (message->FindInt32("media", &media) != B_OK)
|
||||
break;
|
||||
|
||||
if ((fLastMediaStatus & IFM_ACTIVE) == 0
|
||||
@ -163,8 +178,46 @@ AutoconfigLooper::MessageReceived(BMessage* message)
|
||||
_ConfigureIPv4();
|
||||
//_ConfigureIPv6(); // TODO: router advertisement and dhcpv6
|
||||
}
|
||||
|
||||
fLastMediaStatus = media;
|
||||
break;
|
||||
}
|
||||
|
||||
case B_NETWORK_WLAN_SCANNED:
|
||||
{
|
||||
if (fJoiningNetwork || (fLastMediaStatus & IFM_ACTIVE) != 0) {
|
||||
// We already have a link or are already joining.
|
||||
break;
|
||||
}
|
||||
|
||||
fJoiningNetwork = true;
|
||||
// TODO: For now we never reset this flag. We can only do that
|
||||
// after infrastructure has been added to discern a scan reason.
|
||||
// If we would always auto join we would possibly interfere
|
||||
// with active scans in the process of connecting to an AP
|
||||
// either for the initial connection, or after connection loss
|
||||
// to re-establish the link.
|
||||
|
||||
BMessage message(kMsgAutoJoinNetwork);
|
||||
message.AddString("device", fDevice);
|
||||
fTarget.SendMessage(&message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AutoconfigLooper::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgReadyToRun:
|
||||
_ReadyToRun();
|
||||
break;
|
||||
|
||||
case B_NETWORK_MONITOR:
|
||||
_NetworkMonitorNotification(message);
|
||||
break;
|
||||
|
||||
default:
|
||||
BLooper::MessageReceived(message);
|
||||
|
@ -30,11 +30,13 @@ private:
|
||||
void _RemoveClient();
|
||||
void _ConfigureIPv4();
|
||||
void _ReadyToRun();
|
||||
void _NetworkMonitorNotification(BMessage* message);
|
||||
|
||||
BMessenger fTarget;
|
||||
BString fDevice;
|
||||
AutoconfigClient* fCurrentClient;
|
||||
int32 fLastMediaStatus;
|
||||
bool fJoiningNetwork;
|
||||
};
|
||||
|
||||
#endif // AUTOCONFIG_LOOPER_H
|
||||
|
@ -88,7 +88,7 @@ private:
|
||||
void _StartServices();
|
||||
status_t _HandleDeviceMonitor(BMessage* message);
|
||||
|
||||
status_t _AutoJoinNetwork(const char* name);
|
||||
status_t _AutoJoinNetwork(const BMessage& message);
|
||||
status_t _JoinNetwork(const BMessage& message,
|
||||
const char* name = NULL);
|
||||
status_t _LeaveNetwork(const BMessage& message);
|
||||
@ -321,6 +321,12 @@ NetServer::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgAutoJoinNetwork:
|
||||
{
|
||||
_AutoJoinNetwork(*message);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgCountPersistentNetworks:
|
||||
{
|
||||
BMessage reply(B_REPLY);
|
||||
@ -532,26 +538,6 @@ NetServer::_ConfigureInterface(BMessage& message)
|
||||
}
|
||||
}
|
||||
|
||||
BNetworkDevice device(name);
|
||||
if (device.IsWireless() && !device.HasLink()) {
|
||||
const char* networkName;
|
||||
if (message.FindString("network", &networkName) == B_OK) {
|
||||
// join configured network
|
||||
status_t status = _JoinNetwork(message, networkName);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: joining network \"%s\" failed: %s\n",
|
||||
interface.Name(), networkName, strerror(status));
|
||||
}
|
||||
} else {
|
||||
// auto select network to join
|
||||
status_t status = _AutoJoinNetwork(name);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: auto joining network failed: %s\n",
|
||||
interface.Name(), strerror(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up IPv6 Link Local address (based on MAC, if not loopback)
|
||||
_ConfigureIPv6LinkLocal(name);
|
||||
|
||||
@ -671,6 +657,19 @@ NetServer::_ConfigureInterface(BMessage& message)
|
||||
}
|
||||
}
|
||||
|
||||
const char* networkName;
|
||||
if (message.FindString("network", &networkName) == B_OK) {
|
||||
// We want to join a specific network.
|
||||
BNetworkDevice device(name);
|
||||
if (device.IsWireless() && !device.HasLink()) {
|
||||
status_t status = _JoinNetwork(message, networkName);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: joining network \"%s\" failed: %s\n",
|
||||
interface.Name(), networkName, strerror(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (startAutoConfig) {
|
||||
// start auto configuration
|
||||
AutoconfigLooper* looper = new AutoconfigLooper(this, name);
|
||||
@ -987,12 +986,13 @@ NetServer::_HandleDeviceMonitor(BMessage* message)
|
||||
|
||||
|
||||
status_t
|
||||
NetServer::_AutoJoinNetwork(const char* name)
|
||||
NetServer::_AutoJoinNetwork(const BMessage& message)
|
||||
{
|
||||
BNetworkDevice device(name);
|
||||
const char* name = NULL;
|
||||
if (message.FindString("device", &name) != B_OK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BMessage message;
|
||||
message.AddString("device", name);
|
||||
BNetworkDevice device(name);
|
||||
|
||||
// Choose among configured networks
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user