移动宽带 API:“需要 Pin”异常但设置了 pin

Posted

技术标签:

【中文标题】移动宽带 API:“需要 Pin”异常但设置了 pin【英文标题】:Mobile Broadband API: "Pin is required" exception but pin is set 【发布时间】:2012-03-30 15:15:02 【问题描述】:

我正在尝试使用Mobile Broadband API 启动和运行。我在 C# 中使用它,使用找到的说明 here。

我有一个问题:当调制解调器设备被锁定时(即需要 PIN),我想以编程方式设置 pin 并继续建立连接,但后者失败并显示“需要 Pin” ,即使我只是正确设置了 PIN。

Mobile Broadband API 提供IMbnPin 接口来设置引脚,但这是一个异步操作,因此您必须注册OnEnterComplete 事件(IMbnPinEvents 接口的一部分),该事件表明该操作已完成。我认为这应该足够了,但显然不是。

下面的类是一个演示问题的最小的、独立的示例。您可以像这样在控制台应用程序中使用它:

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

(您还需要一个 Interop dll 来编译它,您可以找到 here)

测试类包含一个 ManualResetEvent 字段,用于在 Enter 和 OnEnterComplete 方法之间进行协调。

在Test方法中,我订阅IMbnPinEvents,实例化IMbnPin,调用(异步)Enter方法并调用ManualResetEvent.WaitOne阻塞当前线程。在 OnEnterComplete 中,我可以验证引脚是否已正确设置,然后发送信号 ManualResetEvent,以便测试方法继续执行。如果我在此之后立即继续使用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】:

我找到了答案:我需要等待网络注册激活才能建立连接。事后看来有点明显。为了让它发挥作用,我做了以下更改:

设置pin前,订阅IMbnRegistrationEvents接口 在IMbnRegistrationEvents.OnRegisterStateChange方法中,检查是否 注册状态为“已注册”(即 MBN_REGISTER_STATE_HOME 值之一, MBN_REGISTER_STATE_ROAMING 或 MBN_REGISTER_STATE_PARTNER)。

从此,您可以使用IMbnConnection.Connect方法创建宽带连接。

很难找到这方面的文档...... msdn 上有Mobile Broadband Connection Manager Development Guide,但我在那里找不到任何细节。另外,我不确定这种行为中是否存在特定于提供商或设备的任何内容。

【讨论】:

我遇到了同样的问题,但找不到解释。但是,该问题仅发生在具有临时连接配置文件 (MBN_CONNECTION_MODE.MBN_CONNECTION_MODE_TMP_PROFILE) 的 Windows 7 上。另一方面,在 Windows 10 上,我使用临时连接配置文件没有问题。两台机器属于同一类型。

以上是关于移动宽带 API:“需要 Pin”异常但设置了 pin的主要内容,如果未能解决你的问题,请参考以下文章

怎么查家里宽带无线路由的连接人数!

广东移动宽带的IP和DNS怎么设置?

广东移动宽带的IP和DNS怎么设置

Windows 7 移动宽带 API - 崩溃无一例外

如何将移动宽带 API 添加到我的 C# WPF 应用程序

广东移动宽带的IP和DNS怎么设置