Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
nsNotifyAddrListener Class Reference

#include <nsNotifyAddrListener.h>

Inheritance diagram for nsNotifyAddrListener:
Inheritance graph
[legend]
Collaboration diagram for nsNotifyAddrListener:
Collaboration graph
[legend]

List of all members.

Classes

struct  ChangeEvent

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSINETWORKLINKSERVICE
NS_DECL_NSIRUNNABLE
NS_DECL_NSIOBSERVER 
nsNotifyAddrListener ()
virtual ~nsNotifyAddrListener ()
nsresult Init (void)
NS_IMETHOD Run ()=0
 Defines an entry point for a newly created thread.
void run ()
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.

Public Attributes

readonly attribute boolean isLinkUp
 This is set to true when the system is believed to have a usable network connection.
readonly attribute boolean linkStatusKnown
 This is set to true when we believe that isLinkUp is accurate.

Protected Member Functions

nsresult Shutdown (void)
nsresult SendEventToUI (const char *aEventID)
DWORD GetOperationalStatus (DWORD aAdapterIndex)
DWORD CheckIPAddrTable (void)
 Calls GetIpAddrTable to check whether a link is up.
DWORD CheckAdaptersInfo (void)
 Checks whether a link is up by calling GetAdaptersInfo.
DWORD CheckAdaptersAddresses (void)
void CheckLinkStatus (void)
 Checks the status of all network adapters.
 PR_STATIC_CALLBACK (void *) HandleInterfaceEvent(PLEvent *aEvent)
 PR_STATIC_CALLBACK (void) DestroyInterfaceEvent(PLEvent *aEvent)

Protected Attributes

PRPackedBool mLinkUp
PRPackedBool mStatusKnown
nsCOMPtr< nsIThreadmThread
OSVERSIONINFO mOSVerInfo
HANDLE mShutdownEvent

Detailed Description

Definition at line 48 of file nsNotifyAddrListener.h.


Constructor & Destructor Documentation

NS_DECL_ISUPPORTS NS_DECL_NSINETWORKLINKSERVICE NS_DECL_NSIRUNNABLE NS_DECL_NSIOBSERVER nsNotifyAddrListener::nsNotifyAddrListener ( )

Definition at line 285 of file nsNotifyAddrListener.cpp.

{
    NS_ASSERTION(!mThread, "nsNotifyAddrListener thread shutdown failed");
    FreeIPHelperLibrary();
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 574 of file nsNotifyAddrListener.cpp.

{
    static const DWORD flags =
        GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_SKIP_ANYCAST |
        GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;

    if (!sGetAdaptersAddresses)
        return ERROR_NOT_SUPPORTED;

    ULONG len = 0;

    DWORD ret = sGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len);
    if (ret == ERROR_BUFFER_OVERFLOW) {
        PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES) malloc(len);
        if (addresses) {
            ret = sGetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &len);
            if (ret == ERROR_SUCCESS) {
                PIP_ADAPTER_ADDRESSES ptr;
                BOOL linkUp = FALSE;

                for (ptr = addresses; !linkUp && ptr; ptr = ptr->Next) {
                    if (ptr->OperStatus == IfOperStatusUp &&
                            ptr->IfType != IF_TYPE_SOFTWARE_LOOPBACK)
                        linkUp = TRUE;
                }
                mLinkUp = linkUp;
                mStatusKnown = TRUE;
            }
            free(addresses);
        }
    }
    return ret;
}

Here is the caller graph for this function:

Checks whether a link is up by calling GetAdaptersInfo.

If any adapter's operational status is at least MIB_IF_OPER_STATUS_CONNECTED, checks:

  1. If it's configured for DHCP, the link is considered up if the DHCP server is initialized.
  2. If it's not configured for DHCP, the link is considered up if it has a nonzero IP address. Sets mLinkUp and mStatusKnown if GetAdaptersInfo succeeds. Returns ERROR_SUCCESS on success, and a Win32 error code otherwise. If the call is not present on the current platform, returns ERROR_NOT_SUPPORTED.

Definition at line 531 of file nsNotifyAddrListener.cpp.

{
    if (!sGetAdaptersInfo)
        return ERROR_NOT_SUPPORTED;

    ULONG adaptersLen = 0;

    DWORD ret = sGetAdaptersInfo(0, &adaptersLen);
    if (ret == ERROR_BUFFER_OVERFLOW && adaptersLen > 0) {
        PIP_ADAPTER_INFO adapters = (PIP_ADAPTER_INFO) malloc(adaptersLen);
        if (sGetAdaptersInfo(adapters, &adaptersLen) == ERROR_SUCCESS) {
            PRBool linkUp = PR_FALSE;
            PIP_ADAPTER_INFO ptr;

            for (ptr = adapters; ptr && !linkUp; ptr = ptr->Next) {
                if (GetOperationalStatus(ptr->Index) >=
                        MIB_IF_OPER_STATUS_CONNECTED) {
                    if (ptr->DhcpEnabled) {
                        if (PL_strcmp(ptr->DhcpServer.IpAddress.String,
                                      "255.255.255.255")) {
                            // it has a DHCP server, therefore it must have
                            // a usable address
                            linkUp = PR_TRUE;
                        }
                    }
                    else {
                        PIP_ADDR_STRING ipAddr;
                        for (ipAddr = &ptr->IpAddressList; ipAddr && !linkUp;
                             ipAddr = ipAddr->Next)
                            if (PL_strcmp(ipAddr->IpAddress.String, "0.0.0.0"))
                                linkUp = PR_TRUE;
                    }
                }
            }
            mLinkUp = linkUp;
            mStatusKnown = PR_TRUE;
            free(adapters);
        }
    }
    return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Calls GetIpAddrTable to check whether a link is up.

Assumes so if any adapter has a non-zero IP (v4) address. Sets mLinkUp if GetIpAddrTable succeeds, but doesn't set mStatusKnown. Returns ERROR_SUCCESS on success, and a Win32 error code otherwise.

Definition at line 490 of file nsNotifyAddrListener.cpp.

{
    if (!sGetIpAddrTable)
        return ERROR_CALL_NOT_IMPLEMENTED;

    ULONG size = 0;
    DWORD ret = sGetIpAddrTable(nsnull, &size, FALSE);
    if (ret == ERROR_INSUFFICIENT_BUFFER && size > 0) {
        PMIB_IPADDRTABLE table = (PMIB_IPADDRTABLE) malloc(size);
        if (!table)
            return ERROR_OUTOFMEMORY;

        ret = sGetIpAddrTable(table, &size, FALSE);
        if (ret == ERROR_SUCCESS) {
            PRBool linkUp = PR_FALSE;

            for (DWORD i = 0; !linkUp && i < table->dwNumEntries; i++) {
                if (GetOperationalStatus(table->table[i].dwIndex) >=
                        MIB_IF_OPER_STATUS_CONNECTED &&
                        table->table[i].dwAddr != 0)
                    linkUp = PR_TRUE;
            }
            mLinkUp = linkUp;
        }
        free(table);
    }
    return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Checks the status of all network adapters.

If one is up and has a valid IP address, sets mLinkUp to true. Sets mStatusKnown to true if the link status is definitive.

Definition at line 614 of file nsNotifyAddrListener.cpp.

{
    DWORD ret;
    const char *event;

    ret = CheckAdaptersAddresses();
    if (ret == ERROR_NOT_SUPPORTED)
        ret = CheckAdaptersInfo();
    if (ret == ERROR_NOT_SUPPORTED)
        ret = CheckIPAddrTable();
    if (ret != ERROR_SUCCESS)
        mLinkUp = PR_TRUE; // I can't tell, so assume there's a link

    if (mStatusKnown)
        event = mLinkUp ? NS_NETWORK_LINK_DATA_UP : NS_NETWORK_LINK_DATA_DOWN;
    else
        event = NS_NETWORK_LINK_DATA_UNKNOWN;
    SendEventToUI(event);
}

Here is the call graph for this function:

DWORD nsNotifyAddrListener::GetOperationalStatus ( DWORD  aAdapterIndex) [protected]

Definition at line 463 of file nsNotifyAddrListener.cpp.

{
    DWORD status = MIB_IF_OPER_STATUS_CONNECTED;

    // try to get operational status on WinNT--on Win98, it consistently gives
    // me the wrong status, dagnabbit
    if (mOSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
        // If this fails, assume it's connected.  Didn't find a KB, but it
        // failed for me w/Win2K SP2, and succeeded for me w/Win2K SP3.
        if (sGetIfEntry) {
            MIB_IFROW ifRow;

            ifRow.dwIndex = aAdapterIndex;
            if (sGetIfEntry(&ifRow) == ERROR_SUCCESS)
                status = ifRow.dwOperStatus;
        }
    }
    return status;
}

Here is the caller graph for this function:

Definition at line 348 of file nsNotifyAddrListener.cpp.

{
    // XXX this call is very expensive (~650 milliseconds), so we
    //     don't want to call it synchronously.  Instead, we just
    //     start up assuming we have a network link, but we'll
    //     report that the status isn't known.
    //
    // CheckLinkStatus();

    // only start a thread on Windows 2000 or later
    if (mOSVerInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
        mOSVerInfo.dwMajorVersion < 5)
        return NS_OK;

    nsresult rv;
    nsCOMPtr<nsIObserverService> observerService =
        do_GetService("@mozilla.org/observer-service;1", &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                      PR_FALSE);
    NS_ENSURE_SUCCESS(rv, rv);

    mShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    NS_ENSURE_TRUE(mShutdownEvent, NS_ERROR_OUT_OF_MEMORY);

    rv = NS_NewThread(getter_AddRefs(mThread), this, 0,
                      PR_JOINABLE_THREAD);
    NS_ENSURE_SUCCESS(rv, rv);

    return NS_OK;
}

Here is the call graph for this function:

void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.
void nsIRunnable::run ( ) [inherited]
NS_IMETHOD nsIRunnable::Run ( ) [pure virtual, inherited]
nsresult nsNotifyAddrListener::SendEventToUI ( const char *  aEventID) [protected]

Definition at line 412 of file nsNotifyAddrListener.cpp.

{
    nsresult rv;

    if (!aEventID) return NS_ERROR_NULL_POINTER;

    nsCOMPtr<nsIEventQueue> eq;
    rv = NS_GetMainEventQ(getter_AddRefs(eq));
    if (NS_FAILED(rv))
        return rv;

    ChangeEvent *event = new ChangeEvent(aEventID);
    if (!event)
        return NS_ERROR_OUT_OF_MEMORY;
    // AddRef this because it is being placed in the PLEvent; it'll be Released
    // when DestroyInterfaceEvent is called
    NS_ADDREF_THIS();
    PL_InitEvent(event, this, HandleInterfaceEvent, DestroyInterfaceEvent);

    if (NS_FAILED(rv = eq->PostEvent(event))) {
        NS_ERROR("failed to post event to UI EventQueue");
        PL_DestroyEvent(event);
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 382 of file nsNotifyAddrListener.cpp.

{
    // remove xpcom shutdown observer
    nsCOMPtr<nsIObserverService> observerService =
        do_GetService("@mozilla.org/observer-service;1");
    if (observerService)
        observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);

    if (!mShutdownEvent)
        return NS_OK;

    SetEvent(mShutdownEvent);

    nsresult rv = mThread->Join();

    // Have to break the cycle here, otherwise nsNotifyAddrListener holds
    // onto the thread and the thread holds onto the nsNotifyAddrListener
    // via its mRunnable
    mThread = nsnull;

    CloseHandle(mShutdownEvent);
    mShutdownEvent = NULL;

    return rv;
}

Here is the call graph for this function:


Member Data Documentation

This is set to true when the system is believed to have a usable network connection.

The link is only up when network connections can be established. For example, the link is down during DHCP configuration (unless there is another usable interface already configured).

If the link status is not currently known, we generally assume that it is up.

Definition at line 59 of file nsINetworkLinkService.idl.

This is set to true when we believe that isLinkUp is accurate.

Definition at line 64 of file nsINetworkLinkService.idl.

Definition at line 69 of file nsNotifyAddrListener.h.

OSVERSIONINFO nsNotifyAddrListener::mOSVerInfo [protected]

Definition at line 86 of file nsNotifyAddrListener.h.

Definition at line 87 of file nsNotifyAddrListener.h.

Definition at line 70 of file nsNotifyAddrListener.h.

Definition at line 84 of file nsNotifyAddrListener.h.


The documentation for this class was generated from the following files: