Compartir a través de


Comunicarse con el controlador RIL mediante la interfaz IOemObjectModem

Advertencia

La API COM de telefonía móvil está en desuso en Windows 10. Este contenido se proporciona para admitir el mantenimiento de oem y operador de telefonía móvil creado aplicaciones de Windows Phone 8.1.

Puede usar la interfaz IOemObjectModem para comunicarse con el controlador RIL de OEM. Este es un caso en el que los asociados pueden usar las API de la lista de permitidos de la plataforma restringida (RPAL) para comunicarse con el módem.

Para obtener más información sobre las API COM de telefonía móvil, consulte Referencia de API COM de telefonía móvil.

Uso de LAS API COM de telefonía móvil

Para usar las API COM de telefonía móvil, obtenga un puntero a una instancia IOem Cellular llamando a CoCreateInstanceFromApp. La aplicación que llama necesita este puntero a la interfaz IOemTalk para poder usar la interfaz IOemTalkModem .

El método IOemFinder::RegisterForOemModemExistenceChanges se puede usar para enumerar los módems. Después de llamar al método , se invoca IOemObjectModemExistenceChange::OnOemModemAdded con el puntero IOemDdedModem .

Este código muestra cómo recuperar el puntero IOemCellular mediante CoCreateInstanceFromApp. CoCreateInstanceFromApp puede devolver uno o varios punteros a interfaces específicas. La interfaz deseada es IOemCtion, que se especifica mediante query[0].pIID. OemCellular es una referencia a la clase COM auxiliar; determina el generador que activa la clase .

    MULTI_QI query[1];
    query[0].pIID = &__uuidof(IOemCellular);
    query[0].pItf = nullptr;
    query[0].hr = S_OK;

    hr = CoCreateInstanceFromApp(__uuidof(OemCellular), nullptr, CLSCTX_INPROC_SERVER,
                                nullptr, _countof(query), query);
    ...

Este código muestra el registro de un puntero a IOemAssembliesModemExistenceChange mediante IOemCellular::RegisterForOemModemExistenceChanges. En el código siguiente, se trata de un puntero a CModems que proporciona la interfaz IOem StackModemExistenceChange.

    HRESULT hr;
    hr = m_spCellular->RegisterForOemModemExistenceChanges(this);

    ...

Este código muestra cómo implementar OnOemModemAdded y los demás métodos para la interfaz IOemDdedModemExistenceChange .

class CModems : public IOemCellularModemExistenceChange, public CellBase
{
    ...

    // 
    // IOemCellularModemExistenceChange interface
    //
    IFACEMETHOD(OnOemModemAdded)(IOemCellularModem *pModem);
    IFACEMETHOD(OnOemModemRemoved)(IOemCellularModem *pModem);
    IFACEMETHOD(OnOemModemExistenceDone)();

    ...
};
IFACEMETHODIMP CModems::OnOemModemAdded(IOemCellularModem *pModem)
{
    ComPtr<IOemCellularModem> spModem(pModem);
    m_ModemList.push_back(spModem);
    return S_OK;
}

Envío de datos opacos a RIL

Después de recibir un puntero IOemGroupModem invocando OnOemModemAdded, se puede usar IOemGroupModem::SendModemOpaqueCommand . En segundo plano, el núcleo celular llama a la función RIL_DevSpecific con los parámetros pasados. El controlador RIL controla esta solicitud y devuelve la respuesta a las capas superiores. Después de entregar la respuesta, se invoca una devolución de llamada a IModemOpaqueCommandCompletion::OnModemOpaqueCommandCompletion con el resultado de la llamada SendModemOpaqueCommand .

Este código muestra el envío de datos opacos con IOemGroupModem ::SendModemOpaqueCommand.

    void CCellcoreComponent::CAgent::SetRadioPowerState(bool fPowerOn)
    {
        DWORD command[2];
        command[0] = CMD_SET_EQUIPMENTSTATE;
        command[1] = fPowerOn ? RIL_EQSTATE_FULL : RIL_EQSTATE_MINIMUM;
        m_spModem->SendModemOpaqueCommand(this, (BYTE*)command, sizeof(command), 
            (INT_PTR) CMD_SET_EQUIPMENTSTATE);
    ...

En el ejemplo de código anterior, se envía un comando a RIL para activar o desactivar la radio. El controlador RIL debe diseñarse para controlar los dos elementos de datos DWORD cuando se llama a RIL_DevSpecific . Puede definir su propia estructura y comandos para satisfacer sus necesidades. Después de completar un comando, el controlador RIL envía la respuesta y, a continuación, se invoca una devolución de llamada de finalización (IModemOpaqueCommandCompletion::OnModemOpaqueCommandCompletion).

Este código muestra cómo controlar el evento de finalización de recepción del comando SendModemOpaqueCommand en el ejemplo anterior.

IFACEMETHODIMP CCellcoreComponent::CAgent::OnModemOpaqueCommandCompletion (
            /* [in] */ HRESULT result,
            /* [size_is][in] */ BYTE *pOpaqueResponse,
            /* [in] */ DWORD cbSize,
            /* [in] */ INT_PTR context)
{
    if (SUCCEEDED(result))
    {
        if ((int)context == CMD_SET_EQUIPMENTSTATE)
        {
            //
            // add routine if it is necessary to handle completion.
            //
        }
    }

    return S_OK;
}

Nota:

Tamaño máximo de solicitud, respuesta y notificación : la capa de adaptación de RIL impone una restricción de tamaño máximo de 0x2800 (10240) bytes para las cargas de comando, respuesta y notificación de RIL. Una carga más grande entonces este tamaño generará un error irrecuperable.

Recepción de una notificación de RIL

La interfaz móvil proporciona una serie de RIL notificaciones que comienzan con RIL_NOTIFY, como RIL_NOTIFY_SIGNALQUALITY. Pero IOem GraphModem no proporciona un método predeterminado para recibir estas RIL notificaciones. Una opción es usar IOem ReplicationModem::RegisterForOpaqueModemNotifications para estas notificaciones de RIL de OEM. Para ello, defina primero su propio mensaje de notificación de RIL que sea menor que RIL_NOTIFY_OEM_MAX, que se define en RilAPITypes.h. Cada vez que RIL envía una notificación de RIL de OEM, se llama a IOpaqueModemNotifications::OnOpaqueModemNotifications después de registrar un puntero de devolución de llamada mediante IOem NotificationsModem::RegisterForOpaqueModemNotifications.

Este código muestra cómo llamar a IOemCellularModem::RegisterForOpaqueModemNotifications.

HRESULT CCellcoreComponent::CAgent::Initialize()
{
    ...
    IFFAILED_EXIT(m_spModem->RegisterForOpaqueModemNotifications(this));
    ...

Este código muestra cómo implementar IOpaqueModemNotifications::OnOpaqueModemNotifications. El código contiene un identificador de devolución de llamada de notificación que devuelve el número de barras de señal. El RIL_NOTIFY_OEM_SIGNALSTRENGTH de notificación definido por el personalizado debe implementarse tanto en la aplicación que realiza la llamada como en el controlador RIL.

class CAgent : 
        public IOpaqueModemNotifications, 
        public IModemOpaqueCommandCompletion,
        public IPowerStateChange,
        public IPositionInfoCompletion,
        public IAgent
{
    ...

    //
    // IOpaqueModemNotifications
    //
    IFACEMETHOD(OnOpaqueModemNotifications)( 
    /* [in] */ DWORD dwCode,
    /* [in] */ BYTE *pOpaqueNotification,
    /* [in] */ DWORD cbSize);

                }
IFACEMETHODIMP CCellcoreComponent::CAgent::OnOpaqueModemNotifications( 
            /* [in] */ DWORD dwCode,
            /* [in] */ BYTE *pOpaqueNotification,
            /* [in] */ DWORD cbSize)
{
    wchar_t szResultString[STRING_BUF_LEN] = {0,};

    // check dwCode to fill notification result string.
    if (dwCode == RIL_NOTIFY_OEM_SIGNALSTRENGTH)
    {
        DWORD dwSignalBar;
        if (cbSize == sizeof(DWORD))
        {
            dwSignalBar = *((DWORD*)pOpaqueNotification);
        }
        else
        {
            dwSignalBar = -1;
        }

        swprintf_s(szResultString, STRING_BUF_LEN, L"Num of signal bars : %d", dwSignalBar );
    }
    else
    {
        swprintf_s(szResultString, STRING_BUF_LEN, L"Unknown Notification");
    }

    // send notification string.
    String ^ opaqueInfo = ref new String (szResultString);
    m_cellcore->OnOpaqueNotification(opaqueInfo);

    return S_OK;
}

Guía de diseño de API COM de telefonía móvil

Referencia de LA API COM de telefonía móvil