Condividi tramite


Procedure consigliate per le API a banda larga per dispositivi mobili

Quando si usa l'API Mobile Broadband, il set di procedure consigliate seguente deve essere usato per ottenere le migliori prestazioni possibili.

Non memorizzare nella cache oggetti funzionali

Gli oggetti funzionali, ad esempio IMbnInterface e altri, vengono ottenuti da oggetti di gestione, ad esempio IMbnInterfaceManager, usando il metodo di enumerazione nell'oggetto manager corrispondente. Non memorizzare nella cache questi oggetti funzionali, poiché gli oggetti funzionali memorizzati nella cache contengono dati non aggiornati. Le operazioni sincrone eseguite su questi oggetti funzionali restituiranno gli stessi dati fino a quando non vengono ottenuti di nuovo gli oggetti funzionali.

Memorizzare invece nella cache gli oggetti manager e ottenere gli oggetti funzionali dall'oggetto manager usando il metodo di enumerazione nell'oggetto manager corrispondente per ottenere nuovamente i dati più recenti.

Nell'esempio di codice seguente viene illustrato il modo appropriato per gli oggetti di gestione cache.

#include <atlbase.h>
#include "mbnapi.h"
#include <tchar.h>

int main()
{
    HRESULT hr = E_FAIL;
    int returnVal = 0;

    do
    {
        hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);    
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        CComPtr<IMbnInterfaceManager>  g_InterfaceMgr = NULL;

        //Do the below once(cache the manager objects)
        hr = CoCreateInstance(CLSID_MbnInterfaceManager,
            NULL, 
            CLSCTX_ALL, 
            IID_IMbnInterfaceManager, 
            (void**)&g_InterfaceMgr);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        SAFEARRAY *psa = NULL;

        //Do the below each time(do not cache functional objects)
        hr = g_InterfaceMgr->GetInterfaces(&psa);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        LONG lLower;
        LONG lUpper;

        hr = SafeArrayGetLBound(psa, 1, &lLower);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        hr = SafeArrayGetUBound(psa, 1, &lUpper);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        CComPtr<IMbnInterface>  pInf = NULL;
        MBN_READY_STATE readyState;

        for (LONG l = lLower; l <= lUpper; l++)
        {
            hr = SafeArrayGetElement(psa, &l, (void*)(&pInf));
            if (FAILED(hr))
            {
                returnVal = hr; 
                break;
            }

            hr = pInf->GetReadyState(&readyState);
            if (FAILED(hr))
            {
                returnVal = hr; 
                break;
            }

            _tprintf(_T("Ready State = %d"), readyState); 
        }

        if (FAILED(hr))
        {
            break;
        }
    } while (FALSE);


    CoUninitialize();
    return returnVal;
}

Gestire tutte le notifiche

Seguire e gestire tutte le notifiche, anche se non vengono attivate dall'applicazione. Questa operazione è necessaria per mantenere l'interfaccia utente sincronizzata con lo stato effettivo del dispositivo.

È possibile che in un computer siano in esecuzione più di una gestione connessione. L'interfaccia utente dell'interfaccia di rete disponibile per la visualizzazione nativa fornita da Windows 7 è una gestione connessione. Qualsiasi altra gestione connessione deve rispondere a tutte le notifiche per rimanere sincronizzata con l'interfaccia utente nativa di Windows. Un utente può scegliere di eseguire un'operazione su una delle gestioni connessioni che può causare una modifica dello stato del dispositivo Mobile Broadband. Tuttavia, altre gestioni connessioni devono rimanere aggiornate per indicare correttamente lo stato modificato del dispositivo.

Ad esempio, l'esecuzione di una connessione tramite una delle gestioni connessioni cambierà lo stato del dispositivo da disponibile per la connessione. Questa modifica deve essere visibile alle gestioni connessioni che non hanno avviato questa azione. Tutte le gestioni connessioni con interfaccia utente che indica lo stato di connessione del dispositivo, devono ascoltare e gestire le notifiche sullo stato della connessione per aggiornare correttamente l'interfaccia utente.

Invio e ricezione di byte

Usare le funzioni helper IP GetlfEntry e GetlfEntry2 per inviare e ricevere byte.

Uso dell'API Di sblocco pin

Un'applicazione client chiamante deve essere elevata per richiamare correttamente IMbnPin::Unblock. Questo metodo è l'unica parte dell'API Mobile Broadband che richiede privilegi di amministratore o NCO.

Uso di SafeArrays

  • Usare ZeroMemory() prima di accedere a tutti gli elementi in un oggetto SafeArray.

  • Non controllare gli indici di un oggetto SafeArray. Potrebbero essere negativi.

Nell'esempio di codice seguente viene illustrato come gestire correttamente un oggetto SafeArray.

#include <atlbase.h>
#include "mbnapi.h"

void CreateVisibleProviderList(LPCWSTR interfaceID)
{
    CComPtr<IMbnInterfaceManager>  g_InterfaceMgr = NULL;
    SAFEARRAY *visibleProviders = NULL;
    long visibleLower = 0;
    long visibleUpper = 0;
    MBN_PROVIDER *pProvider = NULL;
    CComPtr<IMbnInterface> pInterface = NULL;

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    if (FAILED(hr))
    {
        goto ERROR_0;
    }

    hr = CoCreateInstance(CLSID_MbnInterfaceManager,
            NULL, 
            CLSCTX_ALL, 
            IID_IMbnInterfaceManager, 
            (void**)&g_InterfaceMgr);
    
    if (FAILED(hr))
    {
        goto ERROR_0;
    }

    hr = g_InterfaceMgr->GetInterface(interfaceID, & pInterface);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    ULONG age;

    hr = pInterface->GetVisibleProviders(&age, &visibleProviders);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    hr = SafeArrayGetLBound(visibleProviders, 1, &visibleLower);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    hr = SafeArrayGetUBound(visibleProviders, 1, &visibleUpper);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    //don't check on the indexes of safearray to be positive
    if (visibleLower > visibleUpper) 
    {
        // There are no visible providers in this case.
        hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
        goto ERROR_0;
    }

    DWORD size = (visibleUpper - visibleLower + 1) * sizeof(BOOL);
    DBG_UNREFERENCED_LOCAL_VARIABLE(size); 
    
    pProvider = (MBN_PROVIDER *)CoTaskMemAlloc(sizeof(MBN_PROVIDER));
    if (!pProvider) 
    {
        hr = E_OUTOFMEMORY;
        goto ERROR_0;
    }

    for (LONG vIndex = visibleLower; vIndex <= visibleUpper; vIndex++) 
    {
        //use zeromemory before accessing any elements in a safearray
        ZeroMemory(pProvider, sizeof(MBN_PROVIDER));
        hr = SafeArrayGetElement(visibleProviders, &vIndex, (void *)pProvider);
        if (FAILED(hr)) 
        {
            continue;
        }
    }

ERROR_0:
    if (visibleProviders) 
    {
        SafeArrayDestroy(visibleProviders);
        visibleProviders = NULL;
    }

    CoUninitialize();
}