Sdílet prostřednictvím


Přehled USSD

Nestrukturovaná data doplňkových služeb (USSD) jsou komunikační protokol používaný zařízeními Global System for Mobile Communications (GSM) ke komunikaci s operátory mobilní sítě (obvykle označované jako "MO").

Abyste pochopili USSD, je užitečné ho porovnat s jeho nejbližším příbuzným: službou krátkých textových zpráv (SMS). USSD i SMS jsou oba GSM standardy, což znamená, že byly zavedeny jako funkce v druhé generaci mobilních zařízení. Na rozdíl od sms je však USSD připojení založené na relaci. Zatímco sms se používá pro krátké zasílání zpráv bez relací, usSD se obvykle používá pro příkaz a řízení mobilního zařízení. Vzhledem k tomu, že je nutné udržovat relaci, USSD nepodporuje schopnost ukládání a přeposílání, kterou SMS podporuje. Zprávy USSD i SMS se odesílají s 7bitovými znaky kompatibilními s GSM, ale USSD dosahuje až 184 znaků na rozdíl od 160 znaků pro SMS.

Zprávy USSD mohou být odeslány z mobilního telefonu otevřením dialeru a zadáním kódu. Ne všechny kódy jsou podporovány každým telefonem nebo MO. V některých případech může telefonní software nebo operační systém zabránit ručnímu odesílání kódů. Jeden požadovaný kód, který musí být implementován, je *#06#. Tento kód vrátí identifikátor IMEI (International Mobile Equipment Identifier) modemu, ale některé telefony vám zabrání vytočení přímo. Pokud se řídíte konvenčními prostředky vyhledání IMEI modemu prostřednictvím nastavení telefonu, toto číslo bylo načteno pomocí tohoto kódu.

Pokud hardware telefonu dokáže přímo zpracovat příkaz kódu, jako je v příkladu IMEI, nebude inicializována žádná síťová relace. Další kódy, které vyžadují síťovou komunikaci, otevřou relaci a pak odešlou zprávu, která se skládá z příkazu a všech nezbytných parametrů, pokud je to možné. Jedním z příkladů je kód, který kontroluje aktuální stav účtu a stav tarifu pomocí MO.

USSD ve Windows se implementuje jako plocha rozhraní API WinRT. Třídy implementace tohoto rozhraní slouží jako stavový počítač pro relace USSD, ale nakonec spoléhá na službu WWAN k provádění náročných operací. Tato rozhraní API se implementují se vzorem továrny.

Implementace USSD

Klíčovou věcí, kterou je potřeba si uvědomit, je, že veřejné rozhraní API je definováno rozhraním IDL. Implementace může být z tohoto důvodu matoucí, zejména pokud neznáte WinRT. Součástí nejasností je zdánlivě nejednoznačné použití slova "továrna". Továrna může odkazovat buď na implementaci třídy statického rozhraní, nebo na skutečnou továrnu, která nabízí rozhraní, jež lze aktivovat, pro třídu běhového prostředí.

Toto téma popisuje koncepty WinRT a pak popisuje implementaci na základě těchto konceptů. Pro další objasnění se vždy můžete obrátit na IDL.

Rozhraní

Rozhraní definují binární rozhraní aplikace (ABI). Popisují funkce, které můžete volat pro libovolnou třídu, která implementuje rozhraní.

Třídy modulu runtime

Jedná se o skutečné třídy. Představují dle názvu to, co je nakonec vystaveno jako názvy tříd v ABI. Každá třída modulu runtime může mít nula nebo více rozhraní (ale musí deklarovat alespoň jedno výchozí rozhraní, pokud má jedno nebo více rozhraní), nula nebo více statických rozhraní a v případě potřeby aktivovatelnou značku. Každé z těchto rozhraní se implementuje v různých souborech jako různé třídy "Impl", ale zdá se, že jsou jedinou sjednocenou třídou pro ABI.

Typické rozhraní se zobrazuje jako metody instance u existujícího objektu.

Statické rozhraní se klientovi jeví jako statické metody v samotné třídě modulu runtime.

Aktivační značka definuje rozhraní továrny, které vytvoří instanci třídy runtime. To je zcela obfuskováno pro klienta, které se zobrazí jako konstruktor pro tuto třídu modulu runtime.

Implementace USSD

Diagram znázorňující implementaci USSD

Tok: Otevřít, Odeslat, Přijmout, Zavřít.

Otevřít, Odeslat

Vývojový diagram znázorňující požadavek USSD s procesem odpovědi

  1. Klient používá jednu ze statických funkcí UssdSession.CreateFromNetworkAccountId nebo UssdSession.CreateFromNetworkInterfaceId k vytvoření objektu UssdSession.

  2. Bez ohledu na volání rozhraní API se k inicializaci ussdSession vyžaduje ID síťového rozhraní. V případě *NetworkAccountID se provede postup načtení ID síťového rozhraní z ID účtu. CreateInternal() se volá k vytvoření instance UssdSession a vyvolání Initialize() v nově vytvořené instanci. Během inicializačních kroků je spuštěno pracovní vlákno a vytvořen popisovač události k aktivaci událostí vlákna. Kroky 3 a 4 se také provádí během inicializace instance().

  3. Initialize() je volána na členském objektu WwanWrapper. Tato funkce přijímá statickou funkci zpětného volání a kontext, aby statická funkce mohla mapovat zpětné volání na kontext objektu.

  4. WwanWrapper otevře popisovač pro WwanService, vytvoří výčet rozhraní a přihlásí se k odběru oznámení USSD tak, že jako kontext poskytne ukazatel funkce statického zpětného volání a "this".

  5. Objekt UssdSession se vrátí klientovi.

  6. Klient vytvoří novou zprávu UssdMessage vyvoláním konstruktoru s řetězcem zprávy. WinRT obfuscuje UssdMessageFactory v tomto procesu.

  7. Klient vyvolá na objektu relace metodu SendMessageAndGetReplyAsync, přičemž předá instanci UssdMessage.

  8. V tuto chvíli SendMessageAndGetReplyAsync vytvoří speciální objekt operace s názvem UssdSendMessageAndGetReplyOperation. Z názvu se zdá, že objekt zapouzdřuje logiku jedné zprávy, která se odesílá dolů do zásobníku (a čeká na odpověď), ale nejedná se o tento případ. WinRT vyžaduje speciální parametr pro asynchronní operace, který můžeme vidět jako druhý parametr definice této funkce.

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

    Jedná se o IUssdSendMessageAndGetReplyOperation, pojmenované rozhraní prostřednictvím typedef, které splňuje tento parametr slibem, že tato operace bude nutně vrátit UssdReply. Toto rozhraní není definováno v IDL, ale je implementováno UssdSendMessageAndGetReplyOperationImpl třídy. Všimněte si, že hlavička pro tuto třídu má speciální rozšíření:

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

    Objekt UssdSendMessageAndGetReplyOperation umožňuje WinRT zamaskovat složitosti této asynchronní operace a veškeré rozdělení a vytváření paměťových proxy spojené s touto operací. Další informace naleznete v tématu SendMessageAndGetReplyAsync.

    Prozatím si uvědomte, že asynchronní operace popsaná výše jednoduše volá zpět do objektu UssdSession, kde je logika pro tuto operaci skutečně obsažena. Můžeme si pro zjednodušení představit, že UssdSession sám o sobě zapouzdřuje práci zde. Nyní můžeme potvrdit, že i přes asynchronní povahu může být současně odeslána pouze jedna zpráva UssdMessage.

    Co ve skutečnosti dělá funkce SendMessageAndGetReplyAsync:

    • Objekt UssdSession se změní na zaneprázdněný stav, uloží obsah UssdMessage a spustí asynchronní akci.
    • OnOperationStart() je vstupním bodem asynchronní logiky. Předpokládejme v tomto scénáři, že neexistuje žádná aktivní relace. Tato funkce vytvoří objekt WWAN_USSD_REQUEST s requestType=WwanUssdRequestInitiate.
    • Kroky 9 a 10 probíhají jako akce prováděné touto funkcí.
  9. m_wwanWrapper.SendRequest je vyvolána pro zpracování práce předání zprávy službě WwanService.

  10. WwanWrapper používá popisovač služby WwanService k vyvolání rozhraní API služby WwanService k provedení akce.

Obdržet

Schéma znázorňující proces příjmu USSD.

Po kroku 10 zůstaneme ve stavu, ve kterém byla do služby WwanService odeslána žádost o inicializaci nové relace USSD a odeslání zprávy USSD v rámci této relace. Po nějaké době bude odpověď k dispozici.

  1. WwanService vyvolá statickou funkci zpětného volání zadanou v kroku 4 s připojeným kontextem.
  2. Kontext se použije k načtení instance WwanWrapper a vyvolání NotificationCallback().
  3. WwanWrapper bude dodržovat stejný vzor jako krok 11, který vyvolá statické zpětné volání do UssdSession a poskytne kontext uložený v kroku 3.
  4. Podobně jako v kroku 12 se kontext používá k vyvolání zpětného volání u instance UssdSession.
  5. UssdSession uchovává WWAN_USSD_EVENT (pod zámkem) a upozorňuje pracovní vlákno, aby zpracovalo událost.
  6. HandleOperationReply() přebírá existující objekt UssdSendMessageAndGetReplyOperationImpl a předává data události do své interní obslužné rutiny.
  7. Operace vytvoří UssdReply a vyvolá FireCompletion() k označení dokončení asynchronní akce.
  8. WinRT obfuskuje dokončení asynchronní akce klientovi. Buď čekali na akci, nebo mají logiku zpětného volání.

Ve stejné relaci je možné odeslat více zpráv. Pokud byla relace zachována, příští typ požadavku bude WwanUssdRequestContinue.

Zavřít

Tokový diagram znázorňující proces ukončení USSD

Po kroku 18 klient obdržel odpověď na zprávu UssdMessage. Mohou nebo nemuseli pokračovat v používání aktivní ussdSession k odesílání dalších zpráv. Předpokládáme, že v určitém okamžiku v budoucnu klient v ussdSession ručně vyvolá Close(). Pokud klient explicitně nevyvolá funkci Close(), bude volána během destruktoru UssdSession.

  1. Klient vyvolá Close() v instanci UssdSession.
  2. WWAN_USSD_REQUEST se vytvoří s RequestType=WwanUssdRequestCancel.
  3. Žádost se odešle do m_wwanWrapper jako v kroku 9.
  4. Požadavek se odešle službě WwanService jako v kroku 10.

Výsledek tohoto požadavku není důležitý. Fakticky je relace uzavřena. I v extrémním hraničním případě, kdy se zpráva nějak nikdy nedoručí, nová relace USSD vždy přepíše existující relaci.

Hardwarová laboratorní sada (HLK) testy

Viz kroky pro instalaci HLK.

V HLK Studiu se připojte k ovladači mobilního modemu a spusťte test: Win6_4.MB. GSM. Data.TestUssd.

Průvodce odstraňováním potíží s USSD v MB

  • Shromážděte a dekódujte protokoly podle pokynů v MB Collecting Logs.

  • Klíčová slova pro filtrování

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

Viz také

MB USSD – operace