API мобильного широкополосного доступа: исключение "Требуется пин-код", но пин-код установлен

Я пытаюсь начать работу с API мобильного широкополосного доступа. Я использую его из C#, используя инструкции, найденные здесь.

У меня проблема с этим, хотя: когда модемное устройство заблокировано (т. Е. Требуется ПИН-код), я хочу установить ПИН-код программно и продолжать устанавливать соединение, но последнее не удается с "ПИН-код требуется", даже если Я просто правильно установил пин-код.

Мобильный широкополосный API предлагает IMbnPin интерфейс для установки пина, но это асинхронная операция, поэтому вы должны зарегистрироваться для OnEnterComplete событие (часть IMbnPinEvents интерфейс), который сигнализирует о завершении операции. Я предполагал, что этого должно быть достаточно, но, видимо, это не так.

Класс ниже представляет собой минимальный, автономный образец, который демонстрирует проблему. Вы можете использовать его в консольном приложении, например так:

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

(Вам также понадобится Interop dll для его компиляции, который вы можете найти здесь)

Тестовый класс содержит поле ManualResetEvent для координации между методами Enter и OnEnterComplete.

В методе 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();
    }

}

1 ответ

Решение

Я нашел ответ: мне нужно было дождаться активации регистрации сети, прежде чем устанавливать соединение. Вид очевидного в ретроспективе. Чтобы это работало, я внес следующие изменения:

  • перед установкой пин-кода, подпишитесь на IMbnRegistrationEvents интерфейс
  • в IMbnRegistrationEvents.OnRegisterStateChange метод, проверьте, является ли состояние регистрации "зарегистрированным" (т. е. одно из значений MBN_REGISTER_STATE_HOME, MBN_REGISTER_STATE_ROAMING или MBN_REGISTER_STATE_PARTNER).

С этого момента вы можете использовать IMbnConnection.Connect способ создания широкополосного соединения.

В некотором роде трудно найти документацию по этому вопросу... На msdn есть Руководство по разработке диспетчера мобильных широкополосных подключений, но я не смог найти там никаких подробностей. Кроме того, я не уверен, что в этом поведении есть что-то специфичное для провайдера или устройства.

Другие вопросы по тегам