我想起床&使用Mobile Broadband API运行。我是在C#中使用它,使用here找到的说明。
我遇到了问题:当调制解调器设备被锁定(即需要PIN)时,我想以编程方式设置引脚并继续进行连接,但后者失败并显示“需要引脚” ,即使我只是正确设置了PIN码。
移动宽带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
信号,以便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();
}
}
答案 0 :(得分:1)
我找到了答案:在进行连接之前,我需要等待网络注册变为活动状态。后见之明显而易见。为了使它工作,我做了以下更改:
IMbnRegistrationEvents
接口IMbnRegistrationEvents.OnRegisterStateChange
方法中,检查是否
注册状态是“已注册”(即MBN_REGISTER_STATE_HOME,其中一个值,
MBN_REGISTER_STATE_ROAMING或MBN_REGISTER_STATE_PARTNER)。 从那时起,您可以使用IMbnConnection.Connect
方法创建宽带连接。
有点难以找到关于这个的文档... msdn上有Mobile Broadband Connection Manager Development Guide,但我找不到任何细节。此外,我不确定此行为中是否存在任何提供程序或设备特定的内容。