1

モバイルブロードバンドAPIを起動して実行しようとしています。ここにある手順を使用して、C#から使用しています。

問題があります。モデムデバイスがロックされている場合(つまり、PINが必要な場合)、プログラムでPINを設定して接続を継続したいのですが、後者は「PINが必要です」で失敗します。 PINを正しく設定しました。

モバイルブロードバンドAPIはIMbnPin、ピンを設定するためのインターフェイスを提供しますが、これは非同期操作であるため、操作が完了したことを通知するOnEnterCompleteイベント(インターフェイスの一部)に登録する必要があります。IMbnPinEventsこれで十分だと思いましたが、そうではないようです。

以下のクラスは、問題を示す最小限の自己完結型のサンプルです。次のようなコンソールアプリケーションで使用できます。

var testInstance = new MbnTest();
testInstance.Test("XXXX"); // replace with actual PIN code

(コンパイルするにはInterop dllも必要です。これはここにあります)

テストクラスには、EnterメソッドとOnEnterCompleteメソッドを調整するためのManualResetEventフィールドが含まれています。

Testメソッドでは、IMbnPinEventsをサブスクライブし、IMbnPinをインスタンス化し、(非同期)Enterメソッドを呼び出し、呼び出しManualResetEvent.WaitOneて現在のスレッドをブロックします。OnEnterCompleteでは、ピンが正しく設定されていることを確認してManualResetEventから、Testメソッドが実行を継続するように信号を送ることができます。その後すぐにTryToGetConnectionState()通話を続けると、例外E_MBN_PIN_REQUIRED(0x80548210)が発生します。Console.ReadLine()を使用して「十分長く」待つと、すべてが正常に機能します。そのため、別のイベントを待つ必要があるように見えますが、どのイベントを見つけることができません。

何か案は?私は何が欠けていますか?

// warning: this is sample code, needs to be better structured for production use
class MbnTest : IMbnPinEvents
{
    private readonly ManualResetEvent _resetEventPin = new ManualResetEvent(false);

    public void Test(string pinCode)
    {
        var interfacemanager = (IMbnInterfaceManager)new MbnInterfaceManager();

        SubscribeToPinEvents(interfacemanager);

        var mbnPin = GetPin(interfacemanager);

        uint requestId;
        Trace.WriteLine("Setting PIN");
        mbnPin.Enter(pinCode, out requestId);
        Trace.WriteLine("Waiting for OnEnterComplete");

        // wait for the OnEnterComplete event
        _resetEventPin.WaitOne();

        Trace.WriteLine("press enter to retrieve connection state");
        Console.ReadLine();

        TryToGetConnectionState();
    }

    void IMbnPinEvents.OnEnterComplete(IMbnPin pin, ref MBN_PIN_INFO pinInfo, uint requestID, int status)
    {
        // reports MBN_PIN_STATE_NONE which means no pin is required
        Trace.WriteLine(string.Format("OnEnterComplete: pin state = {0}", pinInfo.pinState));
        // signal the ManualResetEvent to unblock the thread waiting for the Enter Pin operation to complete
        _resetEventPin.Set();
    }

    private void SubscribeToPinEvents(IMbnInterfaceManager interfacemanager)
    {
        Trace.WriteLine("Subscribing to IMbnPinEvents");
        var guidPinEvents = typeof (IMbnPinEvents).GUID;
        var connectionPointContainer = (IConnectionPointContainer) interfacemanager;
        IConnectionPoint connectionPoint;
        connectionPointContainer.FindConnectionPoint(ref guidPinEvents, out connectionPoint);
        uint cookie;
        connectionPoint.Advise(this, out cookie);
    }

    private static IMbnPin GetPin(IMbnInterfaceManager interfacemanager)
    {
        IMbnInterface mbnInterface = interfacemanager.GetInterfaces().OfType<IMbnInterface>().First();
        Trace.WriteLine(string.Format("mbnInterface: {0}", mbnInterface.GetReadyState()));

        var pinMgr = (IMbnPinManager)mbnInterface;
        var mbnPin = pinMgr.GetPin(MBN_PIN_TYPE.MBN_PIN_TYPE_PIN1);
        return mbnPin;
    }

    private static void TryToGetConnectionState()
    {
        Trace.WriteLine("Retrieving mbn connection");
        var connectionManager = (IMbnConnectionManager)new MbnConnectionManager();
        var mbnConnection = connectionManager.GetConnections().OfType<IMbnConnection>().First();
        Trace.WriteLine(string.Format("connection: {0}", mbnConnection.ConnectionID));
        MBN_ACTIVATION_STATE state;
        string profilename;
        mbnConnection.GetConnectionState(out state, out profilename);
    }


    void IMbnPinEvents.OnChangeComplete(IMbnPin pin, ref MBN_PIN_INFO pinInfo, uint requestID, int status)
    {
        throw new NotImplementedException();
    }

    void IMbnPinEvents.OnEnableComplete(IMbnPin pin, ref MBN_PIN_INFO pinInfo, uint requestID, int status)
    {
        throw new NotImplementedException();
    }

    void IMbnPinEvents.OnDisableComplete(IMbnPin pin, ref MBN_PIN_INFO pinInfo, uint requestID, int status)
    {
        throw new NotImplementedException();
    }


    void IMbnPinEvents.OnUnblockComplete(IMbnPin pin, ref MBN_PIN_INFO pinInfo, uint requestID, int status)
    {
        throw new NotImplementedException();
    }

}
4

1 に答える 1

1

私は答えを見つけました:接続を確立する前に、ネットワーク登録がアクティブになるのを待つ必要がありました。後から考えると明らかです。それを機能させるために、私は次の変更を加えました。

  • IMbnRegistrationEventsピンを設定する前に、インターフェイスにサブスクライブします
  • IMbnRegistrationEvents.OnRegisterStateChangeメソッドで、登録状態が「登録済み」であるかどうかを確認します(つまり、値MBN_REGISTER_STATE_HOME、MBN_REGISTER_STATE_ROAMING、またはMBN_REGISTER_STATE_PARTNERのいずれか)。

それ以降は、このIMbnConnection.Connect方法を使用してブロードバンド接続を作成できます。

これに関するドキュメントを見つけるのはちょっと難しいです... msdnにモバイルブロードバンド接続マネージャー開発ガイドがありますが、そこに詳細を見つけることができませんでした。また、この動作にプロバイダー固有またはデバイス固有のものがあるかどうかもわかりません。

于 2012-04-11T09:34:50.397 に答える