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:
@@ -19,6 +19,7 @@
|
|||||||
#define kMsgRemovePersistentNetwork 'RPnw'
|
#define kMsgRemovePersistentNetwork 'RPnw'
|
||||||
#define kMsgJoinNetwork 'JNnw'
|
#define kMsgJoinNetwork 'JNnw'
|
||||||
#define kMsgLeaveNetwork 'LVnw'
|
#define kMsgLeaveNetwork 'LVnw'
|
||||||
|
#define kMsgAutoJoinNetwork 'AJnw'
|
||||||
|
|
||||||
|
|
||||||
#endif // _NET_SERVER_H
|
#endif // _NET_SERVER_H
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ AutoconfigLooper::AutoconfigLooper(BMessenger target, const char* device)
|
|||||||
fTarget(target),
|
fTarget(target),
|
||||||
fDevice(device),
|
fDevice(device),
|
||||||
fCurrentClient(NULL),
|
fCurrentClient(NULL),
|
||||||
fLastMediaStatus(0)
|
fLastMediaStatus(0),
|
||||||
|
fJoiningNetwork(false)
|
||||||
{
|
{
|
||||||
BMessage ready(kMsgReadyToRun);
|
BMessage ready(kMsgReadyToRun);
|
||||||
PostMessage(&ready);
|
PostMessage(&ready);
|
||||||
@@ -124,7 +125,8 @@ AutoconfigLooper::_ConfigureIPv4()
|
|||||||
void
|
void
|
||||||
AutoconfigLooper::_ReadyToRun()
|
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());
|
BNetworkInterface interface(fDevice.String());
|
||||||
if (interface.HasLink()) {
|
if (interface.HasLink()) {
|
||||||
@@ -139,22 +141,35 @@ AutoconfigLooper::_ReadyToRun()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AutoconfigLooper::MessageReceived(BMessage* message)
|
AutoconfigLooper::_NetworkMonitorNotification(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
int32 opcode;
|
||||||
case kMsgReadyToRun:
|
BString device;
|
||||||
_ReadyToRun();
|
if (message->FindString("device", &device) != B_OK) {
|
||||||
break;
|
if (message->FindString("interface", &device) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
case B_NETWORK_MONITOR:
|
// TODO: Clean this mess up. Wireless devices currently use their
|
||||||
const char* device;
|
// "device_name" in the interface field. First of all the
|
||||||
int32 opcode;
|
// 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;
|
int32 media;
|
||||||
if (message->FindInt32("opcode", &opcode) != B_OK
|
if (message->FindInt32("media", &media) != B_OK)
|
||||||
|| opcode != B_NETWORK_DEVICE_LINK_CHANGED
|
|
||||||
|| message->FindString("device", &device) != B_OK
|
|
||||||
|| fDevice != device
|
|
||||||
|| message->FindInt32("media", &media) != B_OK)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((fLastMediaStatus & IFM_ACTIVE) == 0
|
if ((fLastMediaStatus & IFM_ACTIVE) == 0
|
||||||
@@ -163,8 +178,46 @@ AutoconfigLooper::MessageReceived(BMessage* message)
|
|||||||
_ConfigureIPv4();
|
_ConfigureIPv4();
|
||||||
//_ConfigureIPv6(); // TODO: router advertisement and dhcpv6
|
//_ConfigureIPv6(); // TODO: router advertisement and dhcpv6
|
||||||
}
|
}
|
||||||
|
|
||||||
fLastMediaStatus = media;
|
fLastMediaStatus = media;
|
||||||
break;
|
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:
|
default:
|
||||||
BLooper::MessageReceived(message);
|
BLooper::MessageReceived(message);
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ private:
|
|||||||
void _RemoveClient();
|
void _RemoveClient();
|
||||||
void _ConfigureIPv4();
|
void _ConfigureIPv4();
|
||||||
void _ReadyToRun();
|
void _ReadyToRun();
|
||||||
|
void _NetworkMonitorNotification(BMessage* message);
|
||||||
|
|
||||||
BMessenger fTarget;
|
BMessenger fTarget;
|
||||||
BString fDevice;
|
BString fDevice;
|
||||||
AutoconfigClient* fCurrentClient;
|
AutoconfigClient* fCurrentClient;
|
||||||
int32 fLastMediaStatus;
|
int32 fLastMediaStatus;
|
||||||
|
bool fJoiningNetwork;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUTOCONFIG_LOOPER_H
|
#endif // AUTOCONFIG_LOOPER_H
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ private:
|
|||||||
void _StartServices();
|
void _StartServices();
|
||||||
status_t _HandleDeviceMonitor(BMessage* message);
|
status_t _HandleDeviceMonitor(BMessage* message);
|
||||||
|
|
||||||
status_t _AutoJoinNetwork(const char* name);
|
status_t _AutoJoinNetwork(const BMessage& message);
|
||||||
status_t _JoinNetwork(const BMessage& message,
|
status_t _JoinNetwork(const BMessage& message,
|
||||||
const char* name = NULL);
|
const char* name = NULL);
|
||||||
status_t _LeaveNetwork(const BMessage& message);
|
status_t _LeaveNetwork(const BMessage& message);
|
||||||
@@ -321,6 +321,12 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kMsgAutoJoinNetwork:
|
||||||
|
{
|
||||||
|
_AutoJoinNetwork(*message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kMsgCountPersistentNetworks:
|
case kMsgCountPersistentNetworks:
|
||||||
{
|
{
|
||||||
BMessage reply(B_REPLY);
|
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)
|
// Set up IPv6 Link Local address (based on MAC, if not loopback)
|
||||||
_ConfigureIPv6LinkLocal(name);
|
_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) {
|
if (startAutoConfig) {
|
||||||
// start auto configuration
|
// start auto configuration
|
||||||
AutoconfigLooper* looper = new AutoconfigLooper(this, name);
|
AutoconfigLooper* looper = new AutoconfigLooper(this, name);
|
||||||
@@ -987,12 +986,13 @@ NetServer::_HandleDeviceMonitor(BMessage* message)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
BNetworkDevice device(name);
|
||||||
message.AddString("device", name);
|
|
||||||
|
|
||||||
// Choose among configured networks
|
// Choose among configured networks
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user