Compartir a través de


Información general sobre USSD

Los datos de servicio complementarios no estructurados (USSD) son un protocolo de comunicación utilizado por los dispositivos del sistema global para comunicaciones móviles (GSM) para comunicarse con operadores de red móvil (normalmente denominados simplemente "MO").

Para comprender USSD, resulta útil compararlo con su elemento relacionado más estrechamente: el servicio de mensajes cortos (SMS). USSD y SMS son estándares GSM, lo que significa que se introdujeron como características en la segunda generación de dispositivos móviles. Sin embargo, a diferencia de SMS, USSD es una conexión basada en sesión. Aunque se usa SMS para la mensajería sin sesión corta, USSD se usa normalmente para el comando y el control de un dispositivo móvil. Como es necesario mantener una sesión, USSD no admite la funcionalidad de almacenamiento y reenvío como lo hace SMS. Tanto los mensajes USSD como los SMS se envían con caracteres de 7 bits compatibles con GSM, pero los USSD tienen un máximo de 184 caracteres, frente a los 160 de los SMS.

Los mensajes USSD pueden enviarse desde un teléfono móvil abriendo el marcador y tecleando un código. No todos los códigos son compatibles con todos los teléfonos o MO. En algunos casos, el software telefónico o el sistema operativo pueden impedir el envío manual de códigos. Un código necesario que se debe implementar es *#06#. Este código devuelve el Identificador Internacional de Equipo Móvil (IMEI) del módem, pero algunos teléfonos le impedirán marcarlo directamente. Si sigue los medios convencionales para localizar el IMEI del módem a través de los ajustes de su teléfono, ese número se recuperó utilizando este código.

Si el hardware del teléfono puede controlar directamente el comando de un código como en el ejemplo IMEI, no se iniciará ninguna sesión de red. Otros códigos que requieren comunicación de red abrirán una sesión y, a continuación, enviarán un mensaje que consta de un comando y los parámetros necesarios, si procede. Un ejemplo de ello es un código que comprueba el saldo actual y el estado del plan con el MO.

USSD en Windows se implementa como una superficie de API de WinRT. Las clases de implementación de esta interfaz sirven como la máquina de estado para las sesiones de USSD, pero en última instancia se basan en el servicio WWAN para realizar el trabajo pesado. Estas API se implementan con un patrón de fábrica.

Implementar USSD

Es importante recordar que la API pública está definida por la IDL. La implementación puede resultar confusa debido a esto, especialmente si no está familiarizado con WinRT. Parte de la confusión proviene del uso aparentemente ambiguo de la palabra "fábrica". Una fábrica puede referirse tanto a una implementación de clase de una interfaz estática como a una verdadera fábrica que proporciona una interfaz activable a una clase en tiempo de ejecución.

En este tema se revisan los conceptos de WinRT y, a continuación, se describe la implementación basada en estos conceptos. Siempre puede hacer referencia a la IDL para obtener más aclaraciones.

Interfaces

Las interfaces definen la interfaz binaria de aplicación (ABI). Describen las funciones a las que puede llamar en cualquier clase que implemente la interfaz.

Clases en tiempo de ejecución

Estas son las clases reales. Representan, por nombre, lo que en última instancia se expone como nombres de clase a la ABI. Cada clase en tiempo de ejecución puede tener cero o más interfaces (pero debe declarar al menos una interfaz predeterminada si tiene una o varias interfaces), cero o más interfaces estáticas y una etiqueta activable si es necesario. Cada una de estas interfaces se implementa en archivos diferentes como clases "Impl" diferentes, pero parecen ser una sola clase unificada a la ABI.

Una interfaz típica aparece como métodos de instancia en un objeto existente.

Una interfaz estática aparece al cliente como métodos estáticos en la propia clase en tiempo de ejecución.

Una etiqueta activable define la interfaz de fábrica que generará una instancia de una clase en tiempo de ejecución. Esto se ofusca completamente al cliente, apareciendo como un constructor para esa clase en tiempo de ejecución.

Implementación de USSD

Diagrama que muestra la implementación de USSD.

Flujo: Abrir, Enviar, Recibir, Cerrar.

Abrir, Enviar

Diagrama de flujo que muestra la solicitud USSD con el proceso de respuesta.

  1. El cliente usa una de las funciones estáticas UssdSession.CreateFromNetworkAccountId o UssdSession.CreateFromNetworkInterfaceId para crear el objeto UssdSession.

  2. Independientemente de la API a la que se llama, se requiere un identificador de interfaz de red para inicializar UussdSession. En el caso de *NetworkAccountID, se realizan pasos para recuperar el identificador de la interfaz de red del identificador de cuenta. Se llama a CreateInternal() para crear una instancia de UssdSession e invocar Initialize() en la instancia recién creada. Durante los pasos de inicialización, se activa un subproceso de trabajo y se crea un identificador de eventos para desencadenar eventos para el subproceso. Los pasos 3 y 4 también tienen lugar durante el paso Initialize() de la instancia.

  3. Se llama a Initialize() en el objeto miembro WwanWrapper. Esta función acepta una función de devolución de llamada estática, así como un contexto para permitir que la función estática asigne la devolución de llamada a un contexto de objeto.

  4. WwanWrapper abre un identificador para WwanService, enumera las interfaces y se suscribe a las notificaciones USSD proporcionando un puntero de función de devolución de llamada estática y "this" como contexto.

  5. El objeto UssdSession se devuelve al cliente.

  6. El cliente construye un nuevo UssdMessage invocando el constructor con una cadena de mensaje. WinRT ofusca UssdMessageFactory en este proceso.

  7. El cliente invoca SendMessageAndGetReplyAsync en el objeto de sesión y pasa la instancia de UssdMessage.

  8. En este momento SendMessageAndGetReplyAsync crea un objeto de operación especial denominado UssdSendMessageAndGetReplyOperation. A partir del nombre, parece que el objeto encapsula la lógica de un solo mensaje que se envía a la pila (y espera respuesta), pero no es así. WinRT requiere un parámetro de salida especial para las operaciones asincrónicas, que podemos ver como el segundo parámetro en la definición de esta función.

    HRESULT SendMessageAndGetReplyAsync(
                [in] UssdMessage* message,
                [out, retval] Windows.Foundation.IAsyncOperation<UssdReply>** asyncInfo);
    

    Es el IUssdSendMessageAndGetReplyOperation, una interfaz con nombre a través de typedef, que satisface este parámetro prometiendo que esta operación devolverá inevitablemente un UssdReply. Esta interfaz no está definida en la IDL, pero la implementa la clase UssdSendMessageAndGetReplyOperationImpl. Tenga en cuenta que el encabezado de esta clase tiene una extensión especial:

    class UssdSendMessageAndGetReplyOperationImpl :
        public Microsoft::WRL::RuntimeClass<
            Windows::Networking::NetworkOperators::IUssdSendMessageAndGetReplyOperation,
            Windows::Internal::AsyncBaseFTM<IUssdSendMessageAndGetReplyCompletedHandler, Microsoft::WRL::SingleResult>>
    

    El objeto UssdSendMessageAndGetReplyOperation permite a WinRT ofuscar las complejidades de esta operación asincrónica y toda la compartimentación y proxy de memoria que va junto con ella. Para obtener más información, consulte SendMessageAndGetReplyAsync.

    Por ahora, comprenda que la operación asincrónica descrita anteriormente simplemente llama de nuevo al objeto UssdSession donde realmente se incluye la lógica de esta operación. Podemos visualizar por motivos de simplicidad que el propio UssdSession encapsula el trabajo aquí. Ahora podemos afirmar que, a pesar de la naturaleza asincrónica, solo se puede enviar un UssdMessage a la vez.

    Lo que realmente hace la función SendMessageAndGetReplyAsync:

    • El objeto UssdSession cambia a un estado ocupado, almacena el contenido de UssdMessage y desencadena la acción asincrónica.
    • OnOperationStart() es el punto de entrada de la lógica asincrónica. Supongamos que en este escenario no hay ninguna sesión activa. Esta función crea un objeto WWAN_USSD_REQUEST con RequestType=WwanUssdRequestInitiate.
    • Los pasos 9 y 10 se producen como acciones realizadas por esta función.
  9. m_wwanWrapper.SendRequest se invoca para controlar el trabajo de pasar el mensaje a WwanService.

  10. WwanWrapper usa el identificador wwanService para invocar las API de WwanService para llevar a cabo la acción.

Receive

Diagrama de flujo que muestra el proceso de recepción de USSD.

Después del paso 10, nos quedamos en un estado en el que se envió una solicitud a WwanService para inicializar una nueva sesión de USSD y enviar un mensaje USSD en esa sesión. Después de un tiempo, la respuesta estará disponible.

  1. WwanService invocará la función de devolución de llamada estática proporcionada en el paso 4 con el contexto que también se adjuntó.
  2. El contexto se usará para recuperar la instancia de WwanWrapper e invocar NotificationCallback().
  3. WwanWrapper seguirá el mismo patrón que el paso 11, invocando una devolución de llamada estática a UssdSession, proporcionando el contexto almacenado en el paso 3.
  4. De forma similar al paso 12, el contexto se usa para invocar la devolución de llamada en una instancia de UssdSession.
  5. UssdSession almacena el WWAN_USSD_EVENT (bajo un bloqueo) y notifica al subproceso de trabajo que controle el evento.
  6. HandleOperationReply() toma el objeto UssdSendMessageAndGetReplyOperationImpl existente y pasa los datos del evento a su controlador interno.
  7. La operación construirá y UssdReply e invocará FireCompletion() para marcar la acción asincrónica como finalizada.
  8. WinRT ofusca la finalización de la acción asincrónica al cliente. (Han esperado la acción o tienen lógica de devolución de llamada).

Se pueden enviar más mensajes en la misma sesión. Si se mantiene la sesión, el futuro RequestType será WwanUssdRequestContinue.

Cerrado

Diagrama de flujo que muestra el proceso de cierre de USSD.

Después del paso 18, el cliente ha recibido la respuesta a su UssdMessage. Pueden o no haber seguido usando la UssdSession activa para enviar mensajes adicionales. En algún momento del futuro, el cliente invocará manualmente Close() en UssdSession. Si el cliente no invoca explícitamente Close(), se llamará durante el destructor de UssdSession.

  1. El cliente invoca Close() en la instancia de UssdSession.
  2. Se crea un WWAN_USSD_REQUEST con RequestType=WwanUssdRequestCancel.
  3. La solicitud se envía a m_wwanWrapper como en el paso 9.
  4. La solicitud se envía a WwanService como en el paso 10.

El resultado de esta solicitud no es importante. Para todas las intenciones y propósitos, se cierra la sesión. Incluso en el caso extremo en el que el mensaje nunca se entrega, una nueva sesión de USSD siempre invalidará una sesión existente.

Pruebas del Kit de laboratorio de hardware (HLK)

Consulte Pasos para instalar HLK.

En HLK Studio, conéctese al controlador del módem móvil del dispositivo y ejecute la prueba: Win6_4.MB.GSM.Data.TestUssd.

Guía de solución de problemas de USSD de MB

  • Recopile y descodifique los registros mediante las instrucciones de Registros de recopilación de MB.

  • Palabras clave para el filtrado

    1. OID_WWAN_USSD
    2. NDIS_STATUS_WWAN_USSD
    3. WWAN_USSD_REQUEST
    4. WWAN_USSD_EVENT

Consulte también

Operaciones USSD de MB