共用方式為


USSD 概觀

非結構化補充服務數據(USSD)是全球行動通信系統(GSM)裝置用來與行動網路運營商通訊的通訊協定(通常稱為「MO」)。

若要瞭解 USSD,把它與最類似的技術:簡訊服務(SMS)作比較是有幫助的。 USSD 和 SMS 都是 GSM 標準,這表示它們被引入為第二代行動裝置中的功能。 不過,相較於 SMS,USSD 是以會話為基礎的連線。 雖然 SMS 用於短訊且無會話的傳訊,但 USSD 通常用於行動裝置的指令與控制。 由於維護會話是必要的,所以USSD不支援SMS的儲存和轉寄功能。 USSD 和SMS訊息都會以7位 GSM 相容字元傳送,但USSD的長度上限為184個字元,而SMS則為160。

USSD 訊息可能會從行動電話傳送,方法是開啟撥號程式並輸入代碼。 並非所有電話或MO都支援所有代碼。 在某些情況下,電話軟體或作系統可能會防止手動傳送代碼。 必須實作的其中一個必要程序代碼是 *#06#。 此代碼會傳回調制解調器的國際行動設備標識碼(IMEI),但有些手機會防止您直接撥打此標識符。 如果您遵循透過手機設定尋找數據機 IMEI 的傳統方法,則會使用此程式代碼擷取該號碼。

如果電話硬體可以直接處理程式碼的命令,例如 IMEI 範例,則不會起始任何網路會話。 需要網路通訊的其他程式代碼會開啟會話,然後傳送包含命令和任何必要參數的訊息,如果適用的話。 其中一個範例是程式代碼,它會透過MO來檢查您目前的餘額和計劃狀態。

Windows 中的 USSD 會實作為 WinRT API 介面。 這個介面的實作類別可作為 USSD 工作階段的狀態機器,但最終會依賴 WWAN 服務來執行繁重的工作。 這些 API 是使用工廠模式來實作。

實作USSD

要記住的重點是,公用面向 API 是由 IDL 所定義。 實作可能會造成混淆,特別是如果您不熟悉 WinRT。 混亂的一部分來自看似模棱兩可的「工廠」這個詞的使用。 工廠可以指靜態介面的類別實作,或指提供運行時類別可啟動介面的真正工廠。

本主題會檢閱 WinRT 概念,然後根據這些概念描述實作。 您可以隨時參考IDL以獲得進一步的釐清。

介面

介面會定義應用程式二進位介面 (ABI)。 這些函式描述您可以在任何實作 介面的類別上呼叫的函式。

執行階段類別

這些是實際的類別。 它們最終會以類別名稱的形式公開給 ABI,並以名稱表示。 每個運行時間類別可能都有零或多個介面(但如果有一或多個介面,則必須宣告至少一個預設介面)、零或多個靜態介面,並視需要宣告可啟動的標記。 每個介面都會在不同的檔案中實作為不同的 「Impl」類別,但是它們似乎是 ABI 的單一整合類別。

一般介面會呈現為現有物件上的實例方法。

靜態介面會以運行時間類別本身的靜態方法的形式出現在用戶端上。

可啟動的標記會定義將產生運行時間類別實例的 Factory 介面。 這對客戶端而言是完全隱藏的,並顯示為該運行時類別的建構子。

USSD 實作

顯示USSD實作的圖表。

流程:開啟、傳送、接收、關閉。

開啟、傳送

顯示USSD要求與回復程式的流程圖。

  1. 用戶端會使用其中一個靜態函式 UssdSession.CreateFromNetworkAccountId 或 UssdSession.CreateFromNetworkInterfaceId 來建立 UssdSession 物件。

  2. 不論呼叫的 API 為何,都需要網路介面識別碼才能初始化 UssdSession。 在 *NetworkAccountID 的情況下,將採取措施,從帳戶ID擷取網路介面ID。 CreateInternal() 會呼叫 來建立 UssdSession 的實例,並在新建立的實例上叫用 Initialize()。 在初始化步驟期間,會啟動工作線程,並建立事件處理器以觸發線程事件。 步驟 3 和 4 也會在實例的 Initialize() 期間進行。

  3. Initialize() 會在 WwanWrapper 成員物件上呼叫。 此函式會接受靜態回呼函式以及內容,以允許靜態函式將回呼對應至對象內容。

  4. WwanWrapper 會開啟 WwanService 的操作介面,列舉介面,並透過提供靜態回呼函式指標及 "this" 作為上下文來訂閱 USSD 通知。

  5. UssdSession 物件會傳回給用戶端。

  6. 用戶端透過提供消息字串來調用建構函式,以建立新的UssdMessage。 WinRT 會在這個過程中隱藏 UssdMessageFactory。

  7. 用戶端會在會話物件上叫用 SendMessageAndGetReplyAsync,並傳遞 UssdMessage 實例。

  8. 此時 SendMessageAndGetReplyAsync 會建立名為 UssdSendMessageAndGetReplyOperation 的特殊作業物件。 從名稱來看,該物件似乎將單一訊息的傳遞邏輯封裝進堆疊(並等待回覆),但事實並非如此。 WinRT 需要一個特殊的 out 參數來進行異步操作,我們可以在此函式定義中看到,這是第二個參數。

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

    它是 IUssdSendMessageAndGetReplyOperation,這是透過 typedef 命名的介面,藉由承諾此作業將不可避免地傳回 UssdReply 來滿足此參數。 此介面未定義於IDL中,而是由UssdSendMessageAndGetReplyOperationImpl 類別實作。 請注意,此類別的標頭具有特殊的擴充功能:

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

    UssdSendMessageAndGetReplyOperation 物件可讓 WinRT 隱藏此異步操作的複雜性,以及隨之而來的所有分隔和記憶體代理處理。 如需詳細資訊,請參閱 SendMessageAndGetReplyAsync

    目前,請瞭解上述描述的異步作業僅是回呼 UssdSession 物件,其中實際包含此操作的邏輯。 為了簡單起見,我們可以將UssdSession本身視為封裝了這裡的工作來進行可視化。 我們現在可以斷言,儘管具有異步性質,但一次只能傳送一個 USSD 讯息。

    SendMessageAndGetReplyAsync 函式實際上會執行下列動作:

    • UssdSession 物件會變為忙碌狀態、儲存 UssdMessage 的內容,並觸發異步操作。
    • OnOperationStart() 是異步邏輯的進入點。 假設在此情境中沒有啟動的會話。 此函式會使用 RequestType=WwanUssdRequestInitiate 建立WWAN_USSD_REQUEST物件。
    • 步驟 9 和 10 會隨著此函式所採取的動作而發生。
  9. m_wwanWrapper.SendRequest 會叫用來處理將訊息傳遞至 WwanService 的工作。

  10. WwanWrapper 會使用 WwanService 句柄叫用 WwanService API 來執行動作。

收到

描述 USSD 接收程式的流程圖。

在步驟 10 之後,我們會處於一個已向 WwanService 發送請求來啟動新 USSD 會話,並在該會話中發送 USSD 訊息的狀態。 經過一段時間之後,將會提供回復。

  1. WwanService 會調用步驟 4 中提供的靜態回呼函式,並使用附加的上下文。
  2. 上下文將用來取回 WwanWrapper 實例並調用 NotificationCallback()。
  3. WwanWrapper 會遵循與步驟 11 相同的模式,調用 UssdSession 的靜態回呼,並提供在步驟 3 中儲存的上下文。
  4. 與步驟 12 類似,語境用於在 UssdSession 實例上呼叫回呼。
  5. UssdSession 會儲存 WWAN_USSD_EVENT(在鎖定狀態下),並通知工作線程來處理該事件。
  6. HandleOperationReply() 會採用現有的 UssdSendMessageAndGetReplyOperationImpl 物件,並將事件數據傳遞至其內部處理程式。
  7. 此操作將構建 UssdReply 並調用 FireCompletion() 以將異步操作標記為已完成。
  8. WinRT 將異步操作的完成過程對用戶端進行混淆處理。 (他們要麼等待動作,要麼有回調邏輯。)

您可以在相同的工作階段下傳送更多訊息。 如果會話已被維持,未來的請求類型將是 WwanUssdRequestContinue。

關閉

顯示USSD關閉流程的流程圖。

在步驟 18 之後,用戶端已收到其 UssdMessage 的回復。 他們可能有或沒有繼續使用使用中的 UssdSession 來傳送其他訊息。 我們會假設未來某個時間點,用戶端會在UssdSession上手動叫用 Close()。 如果客戶端未明確地呼叫 Close() 函式,則會在 UssdSession 的解構函式期間自動呼叫它。

  1. 用戶端會在 UssdSession 實例上叫用 Close()。
  2. WWAN_USSD_REQUEST 是使用 RequestType=WwanUssdRequestCancel 建立的。
  3. 要求會傳送至 m_wwanWrapper,如同在步驟 9 中一樣。
  4. 要求會如步驟 10 一樣傳送至 WwanService。

此要求的結果並不重要。 基本上,會議已經結束。 即使在某個極端情況下,訊息從未傳送,新的 USSD 會話仍然會取代現有的會話。

硬體實驗室套件(HLK)測試

請參閱安裝 HLK 步驟。

在 HLK Studio 中,連線到行動數據模組驅動程式並執行測試:Win6_4.MB.GSM.Data.TestUssd

MB USSD 疑難解答指南

  • 根據 MB 收集記錄中的指示來收集和解碼記錄。

  • 篩選的關鍵詞

    1. OID_WWAN_USSD
    2. NDIS_STATUS_WWAN_USSD
    3. WWAN_USSD_REQUEST
    4. WWAN_USSD_EVENT(行動廣域網路 USSD 事件)

另請參閱

MB USSD 作業