C# 移动宽带API:“;Pin是必需的“;异常,但已设置pin

C# 移动宽带API:“;Pin是必需的“;异常,但已设置pin,c#,com,mobile-broadband-api,C#,Com,Mobile Broadband Api,我正试着站起来,和你一起跑步。我使用的是C#,使用的是找到的说明 但我有一个问题:当调制解调器设备被锁定(即需要PIN)时,我想以编程方式设置PIN并继续建立连接,但后者因“需要PIN”而失败,即使我刚刚正确设置了PIN 移动宽带API提供了IMbnPin接口来设置pin,但这是一个异步操作,因此您必须注册onentertcomplete事件(IMbnPinEvents接口的一部分),该事件表示操作已完成。我认为这应该足够了,但显然不是 下面的类是一个最小的、自包含的示例,用于演示该问题。您可以

我正试着站起来,和你一起跑步。我使用的是C#,使用的是找到的说明

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

移动宽带API提供了
IMbnPin
接口来设置pin,但这是一个异步操作,因此您必须注册
onentertcomplete
事件(
IMbnPinEvents
接口的一部分),该事件表示操作已完成。我认为这应该足够了,但显然不是

下面的类是一个最小的、自包含的示例,用于演示该问题。您可以在如下控制台应用程序中使用它:

var testInstance = new MbnTest();
testInstance.Test("XXXX"); // replace with actual PIN code
(您还需要一个互操作dll来编译它,您可以找到)

test类包含一个ManualResetEvent字段,用于协调Enter和OneInterComplete方法

在测试方法中,我订阅IMbnPin事件,实例化IMbnPin,调用(异步)
Enter
方法并调用
ManualResetEvent.WaitOne
来阻止当前线程。在OneInterComplete中,我可以验证引脚是否正确设置,然后向
ManualResetEvent
发送信号,以便继续执行测试方法。如果在此之后立即继续调用
TryToGetConnectionState()
调用,则会得到一个需要的异常E_MBN_PIN_(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();
    }

}
//警告:这是示例代码,需要更好地结构化以供生产使用
B类测试:IMBNPINETS
{
私有只读ManualResetEvent _resetEventPin=新的ManualResetEvent(错误);
公共无效测试(字符串pinCode)
{
var interfacemanager=(IMbnInterfaceManager)新的MbnInterfaceManager();
SubscribeToPinEvents(接口管理员);
var mbnPin=GetPin(interfacemanager);
uint请求id;
Trace.WriteLine(“设置针”);
mbnPin.Enter(pinCode,out requestId);
Trace.WriteLine(“等待一个完成”);
//等待OneInterComplete事件
_resetEventPin.WaitOne();
Trace.WriteLine(“按enter键检索连接状态”);
Console.ReadLine();
TryToGetConnectionState();
}
无效IMbnPinEvents.onenterplete(IMbnPin pin、参考MBN_pin_INFO pinInfo、uint请求ID、int状态)
{
//报告MBN_PIN_STATE_NONE,这意味着不需要PIN
WriteLine(string.Format(“onenterplete:pinState={0}”,pinInfo.pinState));
//向ManualReset事件发送信号,以解锁等待输入销操作完成的螺纹
_resetEventPin.Set();
}
私有无效订阅选项(ImbinterFaceManager接口管理员)
{
Trace.WriteLine(“订阅IMbnPinEvents”);
var guidPinEvents=typeof(IMbnPinEvents).GUID;
var connectionPointContainer=(IConnectionPointContainer)接口管理器;
i连接点连接点;
connectionPointContainer.FindConnectionPoint(ref guidpinents,out connectionPoint);
乌因曲奇;
连接点。建议(此,输出cookie);
}
专用静态IMbnPin GetPin(IMBNterFaceManager接口管理器)
{
IMbnInterface mbnInterface=interfacemanager.GetInterfaces().OfType().First();
WriteLine(string.Format(“mbnInterface:{0}”,mbnInterface.GetReadyState());
var pinMgr=(IMbnPinManager)mbn接口;
var mbnPin=pinMgr.GetPin(MBN_PIN_TYPE.MBN_PIN_TYPE_PIN1);
返回mbnPin;
}
私有静态void TryToGetConnectionState()
{
Trace.WriteLine(“检索mbn连接”);
var connectionManager=(IMbnConnectionManager)new MbnConnectionManager();
var mbnConnection=connectionManager.GetConnections().OfType().First();
WriteLine(string.Format(“连接:{0}”,mbnConnection.ConnectionID));
MBN_激活状态;
字符串profilename;
mbnConnection.GetConnectionState(输出状态,输出配置文件名);
}
作废IMbnPinEvents.OnChangeComplete(IMbnPin pin、参考MBN\u pin\u INFO pinInfo、uint请求ID、int状态)
{
抛出新的NotImplementedException();
}
无效IMbnPinEvents.OnEnableComplete(IMbnPin pin、参考MBN_pin_INFO pinInfo、uint请求ID、int状态)
{
抛出新的NotImplementedException();
}
无效IMbnPinEvents.OnDisableComplete(IMbnPin pin,参考MBN\U pin\U INFO pinInfo,uint请求ID,int状态)
{
抛出新的NotImplementedException();
}
无效IMbnPinEvents.OnUnblockComplete(IMbnPin pin,参考MBN_pin_INFO pinInfo,uint请求ID,int状态)
{
抛出新的NotImplementedException();
}
}

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

  • 设置pin之前,请订阅
    IMbnRegistrationEvents
    界面
  • IMbnRegistrationEvents.OnRegisterStateChange
    方法中,检查 注册状态为“已注册”(即MBN_REGISTER_state_HOME值之一, MBN_寄存器_状态_漫游或MBN_寄存器_状态_伙伴)
从那时起,您可以使用
IMbnConnection.Connect
方法创建宽带连接

很难找到关于这个的文档。。。msdn上有,但我找不到任何细节。此外,我不确定这种行为是否有特定于提供商或设备的内容。

I foun