using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using InTheHand.Net.Sockets;
using InTheHand.Net.Bluetooth;
using InTheHand.Net;
using System.Threading;
using System.Diagnostics;
using ConsoleSystem.ValueType; // Block the use of Console, must use "console".
using System.Reflection;
using InTheHand.Net.Bluetooth.AttributeIds;
namespace ConsoleMenuTesting{
partial class BluetoothTesting
{
public MenuSystem console; //HACK public MenuSystem console;
Stream peer;
public BluetoothTesting()
{
}
//----
static WeakReferenceT<BluetoothClient> s_cli;
class WeakReferenceT<T> : WeakReference
{
public WeakReferenceT(T target)
: base(target)
{
}
public new T Target
{
get { return (T)base.Target; }
set { base.Target = value; }
}
}
//--------
#if DEBUG
[MenuItem]
public void TestPause()
{
console.WriteLine("1111");
console.WriteLine("2222");
console.WriteLine("3333");
console.WriteLine("4444");
console.WriteLine("55555");
console.WriteLine("Before Pause");
console.Pause("Message");
console.WriteLine("After Pause");
}
#endif
#if !NETCF
[MenuItem, SubMenu("Device Discovery")]
public void DiscoDevicesAsync()
{
BluetoothComponent bco = new BluetoothComponent();
bco.DiscoverDevicesComplete += _DiscoDevicesAsync_Callback;
bco.DiscoverDevicesAsync(255, true, true, true, false, 99);
}
void _DiscoDevicesAsync_Callback(object sender, DiscoverDevicesEventArgs e)
{
Debug.Assert((int)e.UserState == 99);
if (e.Cancelled) {
console.WriteLine("DiscoDevicesAsync cancelled.");
} else if (e.Error != null) {
console.WriteLine("DiscoDevicesAsync error: {0}.", Exception_FirstLine(e.Error));
} else {
console.WriteLine("DiscoDevicesAsync found {0} devices.", e.Devices.Length);
}
}
#endif
//--------
BluetoothRadio m_factoryRadio;
BluetoothPublicFactory m_factory;
// TODO Should BluetoothPublicFactory have a Primary/AllRadios property?
/// <summary>
/// --can return null--
/// </summary>
/// <returns></returns>
BluetoothRadio Get_BluetoothRadio()
{
if (m_factory == null)
return BluetoothRadio.PrimaryRadio;
BluetoothRadio radio = m_factoryRadio;
//ClassOfDevice checkNonNull = radio.ClassOfDevice;
return radio;
}
BluetoothDeviceInfo Create_BluetoothDeviceInfo(BluetoothAddress addr)
{
if (m_factory == null)
return new BluetoothDeviceInfo(addr);
return m_factory.CreateBluetoothDeviceInfo(addr);
}
BluetoothClient Create_BluetoothClient()
{
if (m_factory == null)
return new BluetoothClient();
return m_factory.CreateBluetoothClient();
}
BluetoothListener Create_BluetoothListener(Guid svc)
{
if (m_factory == null)
return new BluetoothListener(svc);
return m_factory.CreateBluetoothListener(svc);
}
BluetoothListener Create_BluetoothListener(Guid svc, ServiceRecord record)
{
if (m_factory == null)
return new BluetoothListener(svc, record);
return m_factory.CreateBluetoothListener(svc, record);
}
BluetoothListener Create_BluetoothListener(BluetoothEndPoint ep)
{
if (m_factory == null)
return new BluetoothListener(ep);
return m_factory.CreateBluetoothListener(ep);
}
ObexWebRequest Create_ObexWebRequest(Uri requestUri)
{
if (m_factory == null)
return new ObexWebRequest(requestUri);
return m_factory.CreateObexWebRequest(requestUri);
}
ObexListener Create_ObexListener_Bluetooth()
{
if (m_factory == null)
return new ObexListener(ObexTransport.Bluetooth);
return m_factory.CreateObexListener();
}
[MenuItem]
public void SetStackFactory()
{
BluetoothRadio[] list = BluetoothRadio_GetAll__();
if (list.Length == 0) {
console.WriteLine("No radios found!");
m_factory = null;
m_factoryRadio = null;
}
int choice;
do {
choice = console.ReadInteger(string.Format("Which stack for factory (1-{0}), 0 for \"new\"-direct", list.Length));
} while (choice < 0 || choice > list.Length);
if (choice == 0) {
m_factory = null;
m_factoryRadio = null;
} else {
m_factoryRadio = list[choice - 1];
m_factory = m_factoryRadio.StackFactory;
}
}
//--------
private string GetTime()
{
return Environment.TickCount.ToString();
}
void MiscCallback(IAsyncResult ar)
{
console.WriteLine("{1}: Callback called for \"{0}\"", ar.AsyncState, GetTime());
}
void EmptyCallback(IAsyncResult ar)
{
if (ar.CompletedSynchronously) {
} else {
}
}
bool VerifyConnectionWrite()
{
if (peer == null || !peer.CanWrite) {
console.WriteLine("No connection!");
return false;
}
return true;
}
bool VerifyConnectionRead()
{
if (peer == null || !peer.CanRead) {
console.WriteLine("No connection!");
return false;
}
return true;
}
//--------
[MenuItem, SubMenu("Data")]
public void PrintStreamState()
{
if (peer == null) {
console.WriteLine("Stream is null.");
} else {
console.WriteLine("Stream has CanRead: {0}, CanWrite: {1}.",
peer.CanRead, peer.CanWrite);
}
}
[MenuItem, SubMenu("Data")]
public void CloseStream()
{
if (peer != null) {
peer.Close();
peer = null;
}
}
[MenuItem, SubMenu("Data")]
public void CloseStream_ButDontNullIt()
{
if (peer != null) {
peer.Close();
}
}
[MenuItem, SubMenu("Data")]
public void NullStreamAndClient()
{
peer = null;
s_cli = null;
}
[MenuItem, SubMenu("Data")]
public void CloseClientIfExists()
{
if (s_cli != null) {
BluetoothClient cli = s_cli.Target;
if (cli != null) {
cli.Close();
s_cli = null;
} else {
console.WriteLine("The reference has been GC'd.");
}
}
}
private BluetoothListener ListenInit()
{
Guid svcClass = BluetoothService.Wap;
console.WriteLine("Default UUID : {0}", svcClass);
Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
if (inputGuid.HasValue)
svcClass = inputGuid.Value;
int? port = console.ReadOptionalInteger("Port number");
bool auth = console.ReadYesNo("Authenticate", false);
bool encpt = console.ReadYesNo("Encrypt", false);
bool setPin1, setPin2;
string passcode;
BluetoothAddress pinAddr;
PromptForSetPin(console, out setPin1, out setPin2, out passcode, out pinAddr);
string svcName = console.ReadLine("Service Name (optional)");
if (svcName != null && svcName.Length == 0)
svcName = null;
//
BluetoothEndPoint lep;
if (port == null)
lep = new BluetoothEndPoint(BluetoothAddress.None, svcClass);
else
lep = new BluetoothEndPoint(BluetoothAddress.None, svcClass, port.Value);
console.WriteLine("Going to listen on: {0}:{1}:{2}; auth: {3}, encrypt: {4}.",
lep.Address, lep.Service, lep.Port, auth, encpt);
//
BluetoothListener lsnr = Create_BluetoothListener(lep);
if (svcName != null)
lsnr.ServiceName = svcName;
// Assume false by default, so if NotImpl fails only if user says true.
if (auth)
lsnr.Authenticate = true;
if (encpt)
lsnr.Encrypt = true;
if (setPin1) {
Debug.Assert(pinAddr == null, "pinAddr == null");
//lsnr.SetPin(passcode);
console.WriteLine("Soooorrrrry we don't support SetPin(String) on listener!!!!");
throw new NotSupportedException("ConsoleMenuTesting");
} else if (setPin2) {
Debug.Assert(pinAddr != null, "pinAddr != null");
lsnr.SetPin(pinAddr, passcode);
}
console.WriteLine("Starting Listener...");
lsnr.Start();
BluetoothEndPoint lepLsnr = (BluetoothEndPoint)lsnr.LocalEndPoint;
console.WriteLine("Listening on endpoint: {0}", lepLsnr);
return lsnr;
}
//[MenuItem, SubMenu("BtLsnr")]
//public void ListenStartStopStart()
//{
// Guid svcClass = BluetoothService.Wap;
// console.WriteLine("Default UUID : {0}", svcClass);
// Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
// if (inputGuid.HasValue)
// svcClass = inputGuid.Value;
// BluetoothListener lsnr = Create_BluetoothListener(svcClass);
// lsnr.Start();
// lsnr.Stop();
// lsnr.Start();
// //
// lsnr = null;
// GC.Collect();
// GC.Collect();
// GC.WaitForPendingFinalizers();
//}
[MenuItem, SubMenu("BtLsnr")]
public void Listen()
{
BluetoothListener lsnr = ListenInit();
BluetoothClient cli;
bool startStopStartEtc = console.ReadYesNo("Start-Stop-Start-Stop-Start-Finalize", false);
if (startStopStartEtc) {
lsnr.Stop();
lsnr.Start();
console.WriteLine("Stopped and restarted.");
}
bool async = console.ReadYesNo("Async Accept", false);
if (!async) {
bool callPending = console.ReadYesNo("Loop on Pending()", false);
if (callPending) {
int i = 0;
while (!lsnr.Pending()) {
console.WriteLine("Not Pending" + new string('.', (i + 3) % 3));
const int HalfSecond = 500;
Thread.Sleep(HalfSecond);
++i;
}
console.WriteLine("Is Pending...");
}
//bool closeNow = console.ReadYesNo("Hit return to proceed to EndConnect. Enter Y to call Close first.", false);
console.WriteLine("calling Accept...");
cli = lsnr.AcceptBluetoothClient();
} else {
console.WriteLine("Waiting for connection...");
IAsyncResult ar = lsnr.BeginAcceptBluetoothClient(MiscCallback, "BeginAcceptBluetoothClient");
console.WriteLine("(BeginAccept returned)");
#if !NETCF
ManualResetEvent quit = console.NewManualResetEvent(false);
int signalledIdx = WaitHandle.WaitAny(new WaitHandle[] { ar.AsyncWaitHandle, quit });
if (signalledIdx == 1) {
// ?Do we want to test disposal or Finalization here?
// lsnr.Stop()
peer = null;
return;
}
#endif
cli = lsnr.EndAcceptBluetoothClient(ar);
}
//
peer = cli.GetStream();
console.WriteLine("Got connection from: '{0}' {1}", cli.RemoteMachineName, cli.RemoteEndPoint);
console.Pause("Hit return to continue; and close listener");
if (!startStopStartEtc) {
lsnr.Stop();
} else {
lsnr.Stop();
lsnr.Start();
//
bool x = console.ReadYesNo("Do Async Accept (before Finalization)", false);
IAsyncResult arLast =null;
if (x) {
arLast = lsnr.BeginAcceptBluetoothClient(MiscCallback, "BeginAcceptBluetoothClient");
console.WriteLine("(BeginAccept returned)");
}
lsnr = null;
GC.Collect();
GC.Collect();
GC.WaitForPendingFinalizers();
console.WriteLine("Stopped, restarted, and Finalized.");
if (arLast != null) {
console.WriteLine("arLastL: {0}", arLast.IsCompleted);
// Can't call EndAccept as no lsnr reference!
}
}
}
[MenuItem, SubMenu("BtLsnr")]
public void ListenAndImmediatelyClose()
{
ListenAndImmediatelySendAndClose_(null);
}
[MenuItem, SubMenu("BtLsnr")]
public void ListenAndImmediatelySendOneByteAndClose()
{
ListenAndImmediatelySendAndClose_(new byte[] { (byte)'a' });
}
void ListenAndImmediatelySendAndClose_(byte[] data)
{
BluetoothListener lsnr = ListenInit();
console.WriteLine("Waiting for connection...");
BluetoothClient cli = lsnr.AcceptBluetoothClient();
console.WriteLine("Got connection from: {0}!", cli.RemoteMachineName);
peer = cli.GetStream();
if (data != null)
peer.Write(data, 0, data.Length);
peer.Close();
peer = null;
console.WriteLine("Got connection from ({2}and closed it!): '{0}' {1}",
cli.RemoteMachineName, cli.RemoteEndPoint,
(data != null ? "sent " : string.Empty));
lsnr.Stop();
}
[MenuItem, SubMenu("Data")]
public void SendOneByteAndImmediatelyClose()
{
if (!VerifyConnectionWrite())
return;
byte[] data = { (byte)'a' };
peer.Write(data, 0, data.Length);
peer.Close();
}
[MenuItem, SubMenu("BtLsnr")]
public void ListenAcceptMultiple()
{
BluetoothListener lsnr = ListenInit();
ManualResetEvent quit = console.NewManualResetEvent(false);
ListenAcceptMultipleState state = new ListenAcceptMultipleState();
state.lsnr = lsnr;
state.quit = quit;
bool keepOpen = console.ReadYesNo("Keep reference to all connections?", false);
state.KeepAllConnections = keepOpen;
lsnr.BeginAcceptBluetoothClient(ListenAcceptMultiple_Callback, state);
console.Pause("Hit return to stop accepting");
quit.Set();
lsnr.Stop();
}
struct ListenAcceptMultipleState
{
public BluetoothListener lsnr;
public ManualResetEvent quit;
public int num;
//
bool storeAllConnections;
public List<BluetoothClient> connList;
public bool KeepAllConnections
{
get { return storeAllConnections; }
set
{
storeAllConnections = value;
if (storeAllConnections && connList == null) {
connList = new List<BluetoothClient>();
}
}
}
}
void ListenAcceptMultiple_Callback(IAsyncResult arCb)
{
ListenAcceptMultipleState state = (ListenAcceptMultipleState)arCb.AsyncState;
BluetoothClient cli ;
try {
cli = state.lsnr.EndAcceptBluetoothClient(arCb);
if (state.KeepAllConnections) {
state.connList.Add(cli);
}
} catch (ArgumentException ex) {
console.WriteLine("Accept failed, due to quit? Exiting.");
console.WriteLine(ex);
return;
} catch (ObjectDisposedException ex) {
console.WriteLine("Accept failed, due to quit? Exiting.");
console.WriteLine(ex);
return;
}
Stream peer = cli.GetStream();
console.WriteLine("At " + DateTime.Now.ToLongTimeString() + " got connection #" + (state.num + 1) + " from: '{0}' {1}", cli.RemoteMachineName, cli.RemoteEndPoint);
++state.num;
if (!IsSet(state.quit))
state.lsnr.BeginAcceptBluetoothClient(ListenAcceptMultiple_Callback, state);
}
[MenuItem]
public void NewBtCli()
{
using (BluetoothClient cli = Create_BluetoothClient()) {
console.ReadLine("BluetoothClient created. Continue to dispose");
}
}
[MenuItem]
public void NewBtLsnr()
{
BluetoothListener lsnr = Create_BluetoothListener(BluetoothService.Wap);
try {
console.WriteLine("BluetoothListener created, now calling Start.");
lsnr.Start();
console.ReadLine("Started. Continue to dispose");
} finally {
if (lsnr != null)
lsnr.Stop();
}
}
[MenuItem, SubMenu("BtClient")]
public void Connect()
{
BluetoothClient cli;
Connect_(out cli);
peer = cli.GetStream();
s_cli = new WeakReferenceT<BluetoothClient>(cli);
}
[MenuItem, SubMenu("BtClient")]
public void Connect_FromInquiryCallback()
{
BluetoothClient cliDd = Create_BluetoothClient();
cliDd.BeginDiscoverDevices(255, true, true, true, false,
Connect_FromInquiryCallback_DdCallback, cliDd);
console.WriteLine("Running async DiscoverDevices...");
}
void Connect_FromInquiryCallback_DdCallback(IAsyncResult ar)
{
console.WriteLine("DiscoverDevices completed...");
BluetoothClient cliDd = (BluetoothClient)ar.AsyncState;
cliDd.EndDiscoverDevices(ar);
//
BluetoothClient cli;
Connect_(out cli);
peer = cli.GetStream();
s_cli = new WeakReferenceT<BluetoothClient>(cli);
}
#if TEST_EARLY
[MenuItem, SubMenu("BtClient")]
public void Connect_GetStream2()
{
BluetoothClient cli;
Connect_(out cli);
peer = cli.GetStream2();
s_cli = new WeakReferenceT<BluetoothClient>(cli);
}
#endif
[MenuItem, SubMenu("BtClient")]
public void ConnectSuccessfullyAndImmediatelyClose()
{
ConnectSuccessfullyAndImmediatelySendAndClose_(null);
}
[MenuItem, SubMenu("BtClient")]
public void ConnectSuccessfullyAndImmediatelySendOneByteAndClose()
{
ConnectSuccessfullyAndImmediatelySendAndClose_(new byte[] { (byte)'b' });
}
void ConnectSuccessfullyAndImmediatelySendAndClose_(byte[] data)
{
BluetoothClient cli;
Connect_(out cli);
peer = cli.GetStream();
if (data != null)
peer.Write(data, 0, data.Length);
peer.Close();
peer = null;
s_cli = null;
}
[MenuItem, SubMenu("BtClient")]
public void ConnectMultipleDevices()
{
int num = console.ReadInteger("How many connects?");
bool oaat = console.ReadYesNo("Do one-at-a-time (e.g. Widcomm SDP sync)?", false);
BluetoothAddress[] addrList = new BluetoothAddress[num];
Guid[] svcClassList = new Guid[num];
int?[] portList = new int?[num];
BluetoothClient[] cliList = new BluetoothClient[num];
IAsyncResult[] arList = new IAsyncResult[num];
//
for (int i = 0; i < num; ++i) {
addrList[i] = console.ReadBluetoothAddress("Server #" + (i + 1) + "'s BluetoothAddress");
svcClassList[i] = BluetoothService.Wap;
console.WriteLine("Default UUID : {0}", svcClassList[i]);
Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
if (inputGuid.HasValue)
svcClassList[i] = inputGuid.Value;
portList[i] = console.ReadOptionalInteger("Port number");
}
//
IAsyncResult waitForLast = null;
for (int i = 0; i < num; ++i) {
if (waitForLast != null) {
console.Write("Waiting previous. ");
bool signalled = waitForLast.AsyncWaitHandle.WaitOne(60 * 1000, false);
if (!signalled) {
throw new InvalidOperationException("Timed-out waiting for previous connect to complete.");
}
}
BluetoothEndPoint rep;
if (portList[i] == null)
rep = new BluetoothEndPoint(addrList[i], svcClassList[i]);
else
rep = new BluetoothEndPoint(addrList[i], svcClassList[i], portList[i].Value);
console.WriteLine("{4}: Connecting #{3} to: {0}:{1}:{2} ...", rep.Address, rep.Service, rep.Port,
(i + 1), GetTime());
//
cliList[i] = Create_BluetoothClient();
try {
arList[i] = cliList[i].BeginConnect(rep,
MiscCallback, "BeginConnect #" + (i + 1));
console.WriteLine("{0}: (BeginConnect returned)", GetTime());
if (oaat) {
waitForLast = arList[i];
}
} catch (System.Net.Sockets.SocketException ex) {
console.WriteLine("{0}: BeginConnect failed: {1}", GetTime(), Exception_FirstLine(ex));
}
}//for
//
WaitAll(arList);
console.WriteLine("All signalled");
//
for (int i = 0; i < cliList.Length; i++) {
try {
cliList[i].EndConnect(arList[i]);
} catch (Exception ex) {
console.WriteLine("Error for #{3}: ", (i + 1), Exception_FirstLine(ex));
}
}
console.WriteLine("All completed");
}
private void WaitAll(IList<IAsyncResult> arList)
{
WaitHandle[] whList = GetWaitHandles(arList);
#if !NETCF
bool signalled = WaitHandle.WaitAll(whList);
#else
bool signalled = WaitHandle_WaitAll_Hack(whList);
#endif
Debug.Assert(signalled, "Given infinite timeout, but returned NON-signalled!?!");
}
private WaitHandle[] GetWaitHandles(IList<IAsyncResult> arList)
{
Debug.Assert(arList != null, "ArgNullEx");
List<WaitHandle> output = new List<WaitHandle>(arList.Count);
for (int i = 0; i < arList.Count; ++i) {
if (arList[i] != null)
output.Add(arList[i].AsyncWaitHandle);
}
return output.ToArray();
}
#if NETCF
bool WaitHandle_WaitAll_Hack(WaitHandle[] list)
{
bool sum = true;
foreach (WaitHandle cur in list) {
bool signalled = cur.WaitOne();
Debug.Assert(signalled, "NOT signalled");
sum = sum && signalled;
}
Debug.Assert(sum, "NOT signalled->sum");
return sum;
}
#endif
void Connect_(out BluetoothClient cli)
{
BluetoothAddress addr = console.ReadBluetoothAddress("Server's BluetoothAddress");
Guid svcClass = BluetoothService.Wap;
console.WriteLine("Default UUID : {0}", svcClass);
Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
if (inputGuid.HasValue)
svcClass = inputGuid.Value;
int? port = console.ReadOptionalInteger("Port number");
bool auth = console.ReadYesNo("Authenticate", false);
bool encpt = console.ReadYesNo("Encrypt", false);
bool setPin1, setPin2;
string passcode;
BluetoothAddress pinAddr;
PromptForSetPin(console, out setPin1, out setPin2, out passcode, out pinAddr);
bool async = console.ReadYesNo("Async Connect?", false);
bool asyncCallback = true;//not used but init anyway
if (async) {
asyncCallback = console.ReadYesNo("Async Callback?", true);
}
//
BluetoothEndPoint rep;
if (port == null)
rep = new BluetoothEndPoint(addr, svcClass);
else
rep = new BluetoothEndPoint(addr, svcClass, port.Value);
console.WriteLine("Connecting to: {0}:{1}:{2} ...", rep.Address, rep.Service, rep.Port);
//
cli = Create_BluetoothClient();
// For Auth & Encrypt assume false by default, so if NotImpl fails only if user says true.
if (auth)
cli.Authenticate = true;
if (encpt)
cli.Encrypt = true;
if (setPin1) {
Debug.Assert(pinAddr == null, "pinAddr == null");
cli.SetPin(passcode);
} else if (setPin2) {
Debug.Assert(pinAddr != null, "pinAddr != null");
cli.SetPin(pinAddr, passcode);
}
if (async) {
AsyncCallback cb = null;
if (asyncCallback)
cb = MiscCallback;
IAsyncResult ar = cli.BeginConnect(rep,
cb, "BeginConnect");
console.WriteLine("(BeginConnect returned)");
#if NETCF // ReadYesNo will block the screen. :-(
console.Pause("Paused after BeginConnect");
#endif
bool closeNow = console.ReadYesNo("Hit return to proceed to EndConnect. Enter Y to call Close first.", false);
if (closeNow) {
cli.Close();
}
cli.EndConnect(ar);
} else {
cli.Connect(rep);
}
console.WriteLine("Connected to : '{0}' {1}", cli.RemoteMachineName, cli.RemoteEndPoint);
}
private void PromptForSetPin(MenuSystem console, out bool setPin1, out bool setPin2,
out string passcode, out BluetoothAddress pinAddr)
{
passcode = null;
pinAddr = null;
setPin1 = console.ReadYesNo("SetPin(string)", false);
if (setPin1) {
setPin2 = false;
} else {
setPin2 = console.ReadYesNo("SetPin(address,string)", false);
}
if (setPin1 || setPin2) {
passcode = console.ReadLine("Passcode");
}
if (setPin2) {
pinAddr = console.ReadBluetoothAddress("PIN address");
}
}
[MenuItem, SubMenu("BtClient")]
public void ConnectMultipleTimes()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Server's BluetoothAddress");
Guid svcClass = BluetoothService.Wap;
console.WriteLine("Default UUID : {0}", svcClass);
Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
if (inputGuid.HasValue)
svcClass = inputGuid.Value;
int? port = console.ReadOptionalInteger("Port number");
//
BluetoothEndPoint rep;
if (port == null)
rep = new BluetoothEndPoint(addr, svcClass);
else
rep = new BluetoothEndPoint(addr, svcClass, port.Value);
console.WriteLine("Will connect to: {0}:{1}:{2} ...", rep.Address, rep.Service, rep.Port);
//
int count = console.ReadInteger("Connect how many times");
int? delay = console.ReadOptionalInteger("Delay between each (ms)");
//
BluetoothClient cli = null;
byte[] buf = { 0x61, 0x62, 0x63, 0x64 };
for (int i = 0; i < count; ++i) {
try {
if (delay.HasValue) {
Thread.Sleep(delay.Value);
}
console.Write("Connecting #" + (i + 1) + "...");
cli = Create_BluetoothClient();
cli.LingerState = new System.Net.Sockets.LingerOption(true, 10);
cli.Connect(rep);
console.WriteLine("Connected");
using (Stream peerA = cli.GetStream()) {
peerA.Write(buf, 0, buf.Length);
}
} catch (Exception ex) {
console.Write("Failed: " + ex);
break;
} finally {
if (cli != null) {
cli.Close();
}
}
}
}
[MenuItem, SubMenu("Data")]
public void SendForever()
{
if (!VerifyConnectionWrite())
return;
int interSendPeriod = console.ReadInteger("Inter-send period in milliseconds");
byte[] buf = Encoding.ASCII.GetBytes("____abcdefghijklmnopqrstuvwxyz");
ManualResetEvent quit = console.NewManualResetEvent(false);
Action<Stream> send = delegate(Stream peer2) {
int num = 0;
while (true) {
if (IsSet(quit))
break;
string numString = num.ToString("d4");
Debug.Assert(numString.Length == 4, "numString.Length: " + numString.Length);
unchecked {
buf[0] = (byte)numString[0];
buf[1] = (byte)numString[1];
buf[2] = (byte)numString[2];
buf[3] = (byte)numString[3];
}
peer2.Write(buf, 0, buf.Length);
console.Write(".");
if (IsSet(quit))
break;
Thread.Sleep(interSendPeriod);
++num;
}//while
};
IAsyncResult ar = DelegateExtension.BeginInvoke(send, peer, null, null);
console.Pause("Hit return to stop sending");
quit.Set();
DelegateExtension.EndInvoke(send, ar);
}
[MenuItem, SubMenu("Data")]
public void ZeroLengthSend()
{
if (peer == null)
return;
byte[] buf = new byte[2];
peer.Write(buf, 0, 0);
console.WriteLine("ZeroLengthSend");
}
[MenuItem, SubMenu("Data")]
public void ZeroLengthRead()
{
if (peer == null)
return;
byte[] buf = new byte[2];
IAsyncResult ar = null;
bool doNormalReadFirst = console.ReadYesNo("Do normal async read first", false);
if (doNormalReadFirst)
ar = peer.BeginRead(buf, 0, 1, null, null);
int readLen = peer.Read(buf, 0, 0);
console.WriteLine("Did ZeroLengthRead, got length: {0}", readLen);
if (ar != null) {
int readLen0 = peer.EndRead(ar);
console.WriteLine("The first read got {0} bytes.", readLen0);
}
}
[MenuItem, SubMenu("Data")]
public void SendOneAtATime()
{
if (!VerifyConnectionWrite())
return;
byte[] buf = Encoding.ASCII.GetBytes("____abcdefghijklmnopqrstuvwxyz");
Action<Stream> send = delegate(Stream peer2) {
int num = 0;
while (true) {
string numString = num.ToString("d4");
Debug.Assert(numString.Length == 4, "numString.Length: " + numString.Length);
unchecked {
buf[0] = (byte)numString[0];
buf[1] = (byte)numString[1];
buf[2] = (byte)numString[2];
buf[3] = (byte)numString[3];
}
peer2.Write(buf, 0, buf.Length);
console.Write(".");
if (!console.ReadYesNo("Send another", true))
break;
}//while
};
send.Invoke(peer);
}
private static bool IsSet(ManualResetEvent quit)
{
bool signalled = quit.WaitOne(0, false);
return signalled;
}
[MenuItem, SubMenu("Data")]
public void SendCrLf()
{
if (peer == null || !peer.CanWrite) {
console.WriteLine("No connection!");
return;
}
byte[] buf = Encoding.ASCII.GetBytes("\r\n");
peer.Write(buf, 0, buf.Length);
}
[MenuItem, SubMenu("Data")]
public void ReadForever()
{
if (!VerifyConnectionRead())
return;
byte[] buf = new byte[100];
ManualResetEvent quit = console.NewManualResetEvent(false);
Action<Stream> send = delegate(Stream peer2) {
while (true) {
if (IsSet(quit))
break;
bool success = false;
try {
int readLen = peer2.Read(buf, 0, buf.Length);
console.Write(" len='{0}'", readLen);
success = true;
if (readLen == 0) {
console.WriteLine(" EoS.");
break;
}
} finally {
if (!success)
console.WriteLine("Error!");
}
}//while
};
IAsyncResult ar = DelegateExtension.BeginInvoke(send, peer, null, null);
console.Pause("Hit return to stop after next Read");
quit.Set();
DelegateExtension.EndInvoke(send, ar);
}
[MenuItem, SubMenu("Data")]
public void ReadForeverAndReflect()
{
if (!VerifyConnectionRead())
return;
byte[] buf = new byte[100];
byte[] rsp = new byte[100];
ManualResetEvent quit = console.NewManualResetEvent(false);
Action<Stream> send = delegate(Stream peer2) {
while (true) {
if (IsSet(quit))
break;
int readLen = peer2.Read(buf, 0, buf.Length);
console.Write(" len='{0}'", readLen);
if (readLen == 0) {
console.WriteLine(" EoS.");
break;
}
SwapCase(buf, rsp, readLen);
peer2.Write(rsp, 0, readLen);
}//while
};
IAsyncResult ar = DelegateExtension.BeginInvoke(send, peer, null, null);
console.Pause("Hit return to stop after next Read");
quit.Set();
DelegateExtension.EndInvoke(send, ar);
}
private static void SwapCase(byte[] src, byte[] dst, int len)
{
for (int i = 0; i < len; ++i) {
byte b = src[i];
char ch = (char)b;
char upper = char.ToUpper(ch, System.Globalization.CultureInfo.InvariantCulture);
char lower = char.ToLower(ch, System.Globalization.CultureInfo.InvariantCulture);
char upperBack = char.ToLower(ch, System.Globalization.CultureInfo.InvariantCulture);
char lowerBack = char.ToUpper(ch, System.Globalization.CultureInfo.InvariantCulture);
if (lowerBack != ch && upperBack != ch) {
// didn't round-trip, not a displayable(?) char, return as is.
dst[i] = (byte)ch;
} else if (lower == ch && upper == ch) {
// didn't change, not a alphabetical char, return as is.
dst[i] = (byte)ch;
} else if (lower == ch) { // Is lower case, so return as upper case
Debug.Assert(upper != ch, ((ushort)upper).ToString("X") + " != " + ((ushort)ch).ToString("X"));
dst[i] = (byte)upper;
} else {
Debug.Assert(upper == ch);
Debug.Assert(lower != ch, ((ushort)upper).ToString("X") + " != " + ((ushort)ch).ToString("X"));
dst[i] = (byte)lower;
}
}//for
}
[MenuItem, SubMenu("Data")]
public void SendObexPutInOnePacket()
{
if (!VerifyConnectionWrite())
return;
byte[] bufValid = {
/*PutFinal*/0x82, 0,41,
/*Name*/0x01, 0,19, 0,(byte)'a', 0,(byte)'a', 0,(byte)'a',
0,(byte)'.', 0,(byte)'t', 0,(byte)'x', 0,(byte)'t', 0,0,
/*EoB*/0x49, 0,19, 0,(byte)'a', 0,(byte)'a', 0,(byte)'a',
0,(byte)'.', 0,(byte)'t', 0,(byte)'x', 0,(byte)'t', 0,0
};
byte[] bufTruncatedInFront = {
/*PutFinal*/0x82, 0, // !!!!
};
byte[] bufTruncatedInRear = {
/*PutFinal*/0x82, 0,41,
/*Name*/0x01, 0,19, 0,(byte)'a', // !!!!!
};
byte[] bufTruncateBeforeFinal = {
/*Put-NON-Final*/0x02, 0,41,
/*Name*/0x01, 0,19, 0,(byte)'a', 0,(byte)'a', 0,(byte)'a',
0,(byte)'.', 0,(byte)'t', 0,(byte)'x', 0,(byte)'t', 0,0,
/*Body*/0x48, 0,19, 0,(byte)'a', 0,(byte)'a', 0,(byte)'a',
0,(byte)'.', 0,(byte)'t', 0,(byte)'x', 0,(byte)'t', 0,0
};
int? choice;
while (true) {
choice = console.ReadOptionalInteger(
"1. Complete (one packet), 2. Truncated in front, 3. Truncated in back, 4. Truncated before final packet");
if (!choice.HasValue || (choice.Value >= 1 && choice.Value <= 4))
break;
console.WriteLine("Invalid selection.");
}
byte[] buf;
switch (choice) {
case null:
case 1:
buf = bufValid;
break;
case 2:
buf = bufTruncatedInFront;
break;
case 3:
buf = bufTruncatedInRear;
break;
case 4:
buf = bufTruncateBeforeFinal;
break;
default:
throw new ArgumentException("Invalid selection: " + choice);
}
peer.Write(buf, 0, buf.Length);
peer.Flush(); // just in case
console.ReadLine("Waiting before closing the connection");
peer.Close();
}
//----
[MenuItem, SubMenu("Device Discovery")]
public void DiscoverAll()
{
BluetoothClient cli = Create_BluetoothClient();
DateTime startTime = DateTime.Now;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
DateTime endTime = DateTime.Now;
DumpDeviceInfo(devices, startTime, endTime);
}
[MenuItem, SubMenu("Device Discovery")]
public void DiscoverAllAsync()
{
BluetoothClient cli = Create_BluetoothClient();
const int DefaultTimeout = 30;
TimeSpan? timeout = console.ReadTimeSecondsOptional("Set InquiryLength (default " + DefaultTimeout + "secs)");
if (timeout == null) {
timeout = TimeSpan.FromSeconds(DefaultTimeout);
}
cli.InquiryLength = timeout.Value;
EventHandler dlgt = delegate {
DateTime startTime = DateTime.Now;
DiscoState1 state = new DiscoState1(cli, startTime);
IAsyncResult ar = cli.BeginDiscoverDevices(255,
true, true, true, false,
RestartDiscoCallback, state);
};
#if NETCF
bool fromUi = console.ReadYesNo("Start first discovery from UI thread?", false);
#else
bool fromUi = false;
#endif
if (fromUi) {
console.UiInvoke(dlgt);
} else {
dlgt(null, null);
}
//
console.Pause("Do continue when discovery has completed");
}
class DiscoState1
{
public readonly BluetoothClient cli;
public readonly DateTime startTime;
public DiscoState1(BluetoothClient cli, DateTime startTime)
{
this.cli = cli;
this.startTime =startTime;
}
}
void SimpleDiscoCallback(IAsyncResult ar)
{
DiscoState1 state = (DiscoState1)ar.AsyncState;
try {
BluetoothDeviceInfo[] devices = state.cli.EndDiscoverDevices(ar);
DateTime endTime = DateTime.Now;
DumpDeviceInfoBrief(devices, state.startTime, endTime);
} catch (Exception ex) {
console.WriteLine("Discovery failed with: " + ex);
}
}
void RestartDiscoCallback(IAsyncResult ar)
{
SimpleDiscoCallback(ar);
bool startAgainInCallback = console.ReadYesNo("Start discovery again from callback", false);
if (startAgainInCallback) {
DiscoState1 state0 = (DiscoState1)ar.AsyncState;
DiscoState1 state = new DiscoState1(state0.cli, DateTime.Now);
IAsyncResult ar2 = state.cli.BeginDiscoverDevices(255,
true, true, true, false,
SimpleDiscoCallback, state);
}
}
[MenuItem, SubMenu("Device Discovery")]
public void DiscoverRemembered()
{
BluetoothClient cli = Create_BluetoothClient();
DateTime startTime = DateTime.Now;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices(255, false, true, false);
DateTime endTime = DateTime.Now;
DumpDeviceInfo(devices, startTime, endTime);
}
[MenuItem, SubMenu("Device Discovery")]
public void DiscoverFlags()
{
DiscoverFlags_(false);
}
[MenuItem, SubMenu("Device Discovery")]
void DiscoverFlagsAsync()
{
DiscoverFlags_(true);
}
private void GetDiscoveryFlags(MenuSystem console, out bool discoOnly, out bool auth, out bool rembd, out bool unk)
{
console.WriteLine("Discover which type of remote devices?");
discoOnly = console.ReadYesNo("discoverableOnly", false);
unk = console.ReadYesNo("Unknown", false);
rembd = console.ReadYesNo("Remembered", false);
auth = console.ReadYesNo("Authenticated", false);
}
public void DiscoverFlags_(bool async)
{
BluetoothClient cli = Create_BluetoothClient();
bool discoOnly, auth, rembd, unk;
GetDiscoveryFlags(console, out discoOnly, out auth, out rembd, out unk);
BluetoothDeviceInfo[] devices;
//
TimeSpan? timeout = console.ReadTimeSecondsOptional("InquiryLength");
if (timeout != null) {
cli.InquiryLength = timeout.Value;
}
console.WriteLine("cli.InquiryLength is: {0}", cli.InquiryLength);
//
DateTime startTime = DateTime.Now;
if (async) {
IAsyncResult ar = cli.BeginDiscoverDevices(255, auth, rembd, unk, discoOnly,
MiscCallback, "BeginDiscoverDevices");
console.WriteLine("(BeginDiscoverDevices returned)");
devices = cli.EndDiscoverDevices(ar);
} else {
devices = cli.DiscoverDevices(255, auth, rembd, unk, discoOnly);
}
DateTime endTime = DateTime.Now;
DumpDeviceInfo(devices, startTime, endTime);
bool dispose = console.ReadYesNo("Dispose BtCli", false);
if (dispose && cli != null) {
cli.Dispose();
}
}
[MenuItem, SubMenu("Device Discovery")]
public void Discover_RunAllFlagCombinations()
{
BluetoothClient cli = Create_BluetoothClient();
DateTime startTime = DateTime.Now;
bool discoOnly, authenticated, remembered, unknown;
int flagSource = 0;
while (true) {
authenticated = (flagSource & 1) != 0;
remembered = (flagSource & 2) != 0;
unknown = (flagSource & 4) != 0;
discoOnly = (flagSource & 8) != 0;
//
BluetoothDeviceInfo[] devices = cli.DiscoverDevices(255,
authenticated, remembered, unknown, discoOnly);
console.WriteLine("Got {0} results", devices.Length);
//
if (authenticated && remembered && unknown && discoOnly)
break; // Have tested all cases of the original four flags.
++flagSource;
Thread.Sleep(2000); // This sequence hangs on my W2k+Widcomm box -- does delaying help...?
}//while
//DateTime endTime = DateTime.Now;
//DumpDeviceInfo(devices, startTime, endTime);
console.WriteLine("All DiscoverDevices flag combinations run.");
}
const string vbCrLf = "\r\n";
void DumpDeviceInfo(BluetoothDeviceInfo[] devices,
DateTime startTime, DateTime endTime)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
DateTime localTime = startTime.ToLocalTime();
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Discovery process started at {0} UTC, {1} local, and ended at {2} UTC.",
startTime, localTime, endTime);
sb.Append(vbCrLf + vbCrLf);
console.WriteLine(sb.ToString());
foreach (BluetoothDeviceInfo curDevice in devices) {
sb.Length = 0;
DumpDeviceInfo(sb, curDevice);
console.WriteLine(sb.ToString());
}
}
void DumpDeviceInfoBrief(BluetoothDeviceInfo[] devices,
DateTime startTime, DateTime endTime)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
DateTime localTime = startTime.ToLocalTime();
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Discovery process started at {0} UTC, {1} local, and ended at {2} UTC.",
startTime, localTime, endTime);
console.WriteLine(sb.ToString());
foreach (BluetoothDeviceInfo curDevice in devices) {
sb.Length = 0;
DumpDeviceInfoBrief(sb, curDevice);
console.WriteLine(sb.ToString());
}
}
private static void DumpDeviceInfoBrief(StringBuilder sb, BluetoothDeviceInfo curDevice)
{
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"* {0}", curDevice.DeviceName);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
", Address: {0}", curDevice.DeviceAddress);
}
private static string DumpDeviceInfoBrief(BluetoothDeviceInfo curDevice)
{
System.Text.StringBuilder sb = new StringBuilder();
DumpDeviceInfoBrief(sb, curDevice);
return sb.ToString();
}
private static void DumpDeviceInfo(System.Text.StringBuilder sb, BluetoothDeviceInfo curDevice)
{
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"* {0}", curDevice.DeviceName);
sb.Append(vbCrLf);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Address: {0}", curDevice.DeviceAddress);
sb.Append(vbCrLf);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Remembered: {2}, Authenticated: {0}, Connected: {1}",
curDevice.Authenticated, curDevice.Connected, curDevice.Remembered);
sb.Append(vbCrLf);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"LastSeen: {0} ({2}), LastUsed: {1} ({3})",
curDevice.LastSeen, curDevice.LastUsed,
curDevice.LastSeen.Kind, curDevice.LastUsed.Kind);
sb.Append(vbCrLf);
DumpCodInfo(curDevice.ClassOfDevice, sb);
Int32 rssi = curDevice.Rssi;
if (rssi != Int32.MinValue) {
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Rssi: {0} (0x{0:X})", rssi);
} else {
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"Rssi: failed");
}
sb.Append(vbCrLf);
}
private static string DumpDeviceInfo(BluetoothDeviceInfo curDevice)
{
System.Text.StringBuilder sb = new StringBuilder();
DumpDeviceInfo(sb, curDevice);
return sb.ToString();
}
static void DumpCodInfo(ClassOfDevice cod, System.Text.StringBuilder sb)
{
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
"CoD: (0x{0:X6})", cod.Value, cod);
sb.Append(vbCrLf);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
" Device: {0} (0x{1:X2}) / {2} (0x{3:X4})", cod.MajorDevice, (int)cod.MajorDevice, cod.Device, (int)cod.Device);
sb.Append(vbCrLf);
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture,
" Service: {0} (0x{1:X2})", cod.Service, (int)cod.Service);
sb.Append(vbCrLf);
}
[MenuItem, SubMenu("Device Discovery")]
public void DiscoveryUi()
{
bool discoOnly, auth, rembd, unk;
GetDiscoveryFlags(console, out discoOnly, out auth, out rembd, out unk);
InTheHand.Windows.Forms.SelectBluetoothDeviceDialog dlg = new InTheHand.Windows.Forms.SelectBluetoothDeviceDialog();
dlg.ShowAuthenticated = auth;
dlg.ShowRemembered = rembd;
dlg.ShowUnknown = unk;
System.Windows.Forms.DialogResult rslt = dlg.ShowDialog();
console.WriteLine("DialogResult: {0}, Selected: {1}", rslt,
dlg.SelectedDevice == null ? "(null)" : ("'" + dlg.SelectedDevice.DeviceName + "' " + dlg.SelectedDevice.DeviceAddress.ToString("C")));
}
//----
#if TEST_EARLY
[MenuItem, SubMenu("SDP")]
public void HackServiceDiscovery()
{
BluetoothAddress addr = console.ReadBluetoothAddress("SDP server BluetoothAddress");
try {
BluetoothClient cli0 = new BluetoothClient();
// Don't dispose this to check its Finalization.
InTheHand.Net.Bluetooth.Widcomm.ISdpDiscoveryRecordsBuffer recs
= cli0.WidcommHack__GetServiceRecordsUnparsed(addr, BluetoothService.L2CapProtocol);
console.WriteLine("recordCount: {0}", recs.RecordCount);
//
int[] ports = recs.Hack_GetPorts();
#if !NETCF
string[] txtArr = Array.ConvertAll<int, string>(ports,
delegate(int cur) { return cur.ToString(); });
#else
string[] txtArr = new string[ports.Length];
for (int i = 0; i < ports.Length; ++i)
txtArr[i] = ports[i].ToString();
#endif
string txt = string.Join(", ", txtArr);
console.WriteLine("Ports: {0}", txt);
//
ServiceRecord[] recordArr = recs.GetServiceRecords();
foreach (ServiceRecord cur in recordArr) {
console.WriteLine(
ServiceRecordUtilities.Dump(cur));
}
} catch (Exception ex) {
console.WriteLine(ex);
}
}
#endif
[MenuItem, SubMenu("SDP")]
public void SdpQuery()
{
SdpQuery_();
}
void SdpQuery_()
{
BluetoothAddress addr = console.ReadBluetoothAddress("SDP server BluetoothAddress");
Guid? svcClass = console.ReadOptionalBluetoothUuid("Search UUID (default L2CAP->all)");
if (svcClass == null) {
svcClass = BluetoothService.L2CapProtocol;
}
bool async = console.ReadYesNo("Async Get", true);
try {
BluetoothDeviceInfo bdi = Create_BluetoothDeviceInfo(addr);
ServiceRecord[] recordArr;
if (async) {
console.WriteLine("Calling BeginGetServiceRecords({0})", (Guid)svcClass);
IAsyncResult ar = bdi.BeginGetServiceRecords((Guid)svcClass,
MiscCallback, "BeginGetServiceRecords");
console.WriteLine("BeginGetServiceRecords returned");
recordArr = bdi.EndGetServiceRecords(ar);
} else {
console.WriteLine("Calling GetServiceRecords({0})", (Guid)svcClass);
recordArr = bdi.GetServiceRecords((Guid)svcClass);
}
//
console.WriteLine("recordCount: {0}", recordArr.Length);
int i = 1;
foreach (ServiceRecord cur in recordArr) {
console.WriteLine("{0})", i);
console.WriteLine(
ServiceRecordUtilities.Dump(cur));
console.WriteLine("----");
++i;
}
} catch (Exception ex) {
console.WriteLine(ex);
}
}
[MenuItem, SubMenu("SDP")]
public void SdpCreateCustom()
{
ServiceRecord record = CreateAVariousRecord();
BluetoothListener lsnr = Create_BluetoothListener(BluetoothService.HealthDeviceSink,
record);
lsnr.Start();
console.Pause("Hit return to stop the server");
lsnr.Stop();
}
private static ServiceRecord CreateAVariousRecord()
{
MyFunc<ElementType, ServiceAttributeId> createId = delegate(ElementType etX) {
return (ServiceAttributeId)0x4000 + checked((byte)etX);
};
ServiceRecordBuilder bldr = new ServiceRecordBuilder();
bldr.AddServiceClass(BluetoothService.HealthDevice);
bldr.ServiceName = "alan";
IList<ServiceAttribute> attrList = new List<ServiceAttribute>();
ElementType et_;
#if SUPPORT_NIL
et_ = ElementType.Nil;
attrList.Add(new ServiceAttribute(createId(et_), new ServiceElement(et_, null)));
#endif
et_ = ElementType.Boolean;
attrList.Add(new ServiceAttribute(createId(et_), new ServiceElement(et_, true)));
ElementType[] weee = {
ElementType.UInt8, ElementType.UInt16, ElementType.UInt32, ElementType.UInt64, //UInt128,
ElementType.Int8, ElementType.Int16, ElementType.Int32, ElementType.Int64, //Int128,
};
foreach (ElementType et in weee) {
attrList.Add(new ServiceAttribute(
createId(et),
ServiceElement.CreateNumericalServiceElement(et, (uint)et)));
}
et_ = ElementType.Uuid16;
attrList.Add(new ServiceAttribute(createId(et_),
new ServiceElement(et_, (UInt16)et_)));
et_ = ElementType.Uuid32;
attrList.Add(new ServiceAttribute(createId(et_),
new ServiceElement(et_, (UInt32)et_)));
et_ = ElementType.Uuid128;
attrList.Add(new ServiceAttribute(createId(et_),
new ServiceElement(et_, BluetoothService.CreateBluetoothUuid((int)et_))));
bldr.AddCustomAttributes(attrList);
bldr.AddCustomAttributes(ElementsAndVariableAndFixedInDeepTree1());
ServiceRecord record = bldr.ServiceRecord;
return record;
}
public const String RecordBytes_OneString_StringValue = "abcd\u00e9fgh\u012dj";
public static IList<ServiceAttribute> ElementsAndVariableAndFixedInDeepTree1()
{
IList<ServiceAttribute> attrs = new List<ServiceAttribute>();
//
String str = RecordBytes_OneString_StringValue;
ServiceElement itemStr1 = new ServiceElement(ElementType.TextString, str);
ServiceElement itemStr2 = new ServiceElement(ElementType.TextString, str);
//
Uri uri = new Uri("http://example.com/foo.txt");
ServiceElement itemUrl = new ServiceElement(ElementType.Url, uri);
//
ServiceElement itemF1 = new ServiceElement(ElementType.UInt16, (UInt16)0xfe12);
ServiceElement itemF2 = new ServiceElement(ElementType.UInt16, (UInt16)0x1234);
//
IList<ServiceElement> leaves2 = new List<ServiceElement>();
leaves2.Add(itemStr1);
leaves2.Add(itemUrl);
leaves2.Add(itemF1);
ServiceElement e2 = new ServiceElement(ElementType.ElementSequence, leaves2);
//
ServiceElement e1 = new ServiceElement(ElementType.ElementSequence, e2);
//
IList<ServiceElement> leaves0 = new List<ServiceElement>();
leaves0.Add(e1);
leaves0.Add(itemStr2);
leaves0.Add(itemF2);
attrs.Add(
new ServiceAttribute(0x0401, new ServiceElement(ElementType.ElementAlternative,
leaves0)));
return attrs;
}
[MenuItem, SubMenu("SDP")]
public void SdpCreateDeviceInfoRecord()
{
ServiceRecord record = CreateADeviceInfoRecord();
BluetoothListener lsnr = Create_BluetoothListener(BluetoothService.HealthDeviceSink,
record);
lsnr.Start();
console.Pause("Hit return to stop the server");
lsnr.Stop();
}
private ServiceRecord CreateADeviceInfoRecord()
{
ServiceRecordBuilder bldr = new ServiceRecordBuilder();
// Listener needs this. :-(
bldr.ProtocolType = BluetoothProtocolDescriptorType.GeneralObex;
bldr.AddServiceClass(BluetoothService.PnPInformation);
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.SpecificationId,
ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 1)));
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.VendorId,
ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 2)));
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.ProductId,
ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 3)));
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.Version,
ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 4)));
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.PrimaryRecord,
new ServiceElement(ElementType.Boolean, true)));
bldr.AddCustomAttribute(new ServiceAttribute(DeviceIdProfileAttributeId.VendorIdSource,
ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 6)));
return bldr.ServiceRecord;
}
delegate TResult MyFunc<T0, TResult>(T0 p0);
delegate TResult MyFunc<T0, T1, TResult>(T0 p0, T1 p1);
//----
[MenuItem, SubMenu("Data")]
public void SendLots()
{
if (!VerifyConnectionWrite())
return;
byte[] data = MakeLotsData();
Lots_CheckTheTest(ref data);
bool async = console.ReadYesNo("Async", true);
if (async) {
IAsyncResult ar = peer.BeginWrite(data, 0, data.Length, MiscCallback, "BeginWrite");
console.WriteLine("Started writing (async), len: {0}.", data.Length);
peer.EndWrite(ar);
} else {
peer.Write(data, 0, data.Length);
}
console.WriteLine("Finished writing.");
}
[MenuItem, SubMenu("Data")]
public void SendLots_InSizedChunks()
{
if (!VerifyConnectionWrite())
return;
byte[] data = MakeLotsData();
Lots_CheckTheTest(ref data);
IList<byte[]> dataList = SplitIntoChunks(data, 999);
bool async = console.ReadYesNo("Async", true);
if (async) {
List<IAsyncResult> arList = new List<IAsyncResult>(dataList.Count);
int total = 0;
foreach (byte[] cur in dataList) {
IAsyncResult ar = peer.BeginWrite(cur, 0, cur.Length, EmptyCallback, "BeginWrite");
total += cur.Length;
console.Write(".");
arList.Add(ar);
}
console.WriteLine("Did BeginWrite all chunks ({2}, async), len: {0} is {1}.", total, data.Length, arList.Count);
foreach (IAsyncResult cur in arList) {
peer.EndWrite(cur);
}
console.WriteLine("Did EndWrite all chunks.");
} else {
foreach (byte[] chunk in dataList) {
console.WriteLine("chunk={0}", chunk.Length);
peer.Write(chunk, 0, chunk.Length);
}
}
console.WriteLine("Finished writing.");
}
private void Lots_CheckTheTest(ref byte[] data)
{
bool testChecking1 = console.ReadYesNo("check the TEST, set one byte wrong", false);
if (testChecking1) {
data[1030000] ^= 255;
}
int hackOffset = 1040000;
bool testChecking2 = console.ReadYesNo("check the TEST, add two bytes at " + hackOffset, false);
if (testChecking2) {
byte[] dataSlodged = new byte[data.Length + 2];
Array.Copy(data, 0, dataSlodged, 0, hackOffset);
Array.Copy(data, hackOffset, dataSlodged, 2 + hackOffset, data.Length - hackOffset);
data = dataSlodged;
}
}
private IList<byte[]> SplitIntoChunks(byte[] data, int chunkSize)
{
int offset = 0;
List<byte[]> chunkList = new List<byte[]>(data.Length / chunkSize + 1);
while (offset < data.Length) {
int curSize = Math.Min(chunkSize, data.Length - offset);
byte[] cur = new byte[curSize];
Array.Copy(data, offset, cur, 0, cur.Length);
offset += cur.Length;
chunkList.Add(cur);
}
if (offset != data.Length)
throw new InvalidOperationException("NOT offset==data.Length: " + offset + " vs " + data.Length);
return chunkList;
}
private byte[] MakeLotsData()
{
byte[] data = new byte[1 * 1024 * 1024];
bool useRandom = console.ReadYesNo("Random data", true);
if (useRandom) {
Random r = new Random(999);
r.NextBytes(data);
} else {
for (int i = 0; i < data.Length; ++i) {
data[i] = unchecked((byte)i);
if (data[i] == 0) // Don't allow zeros, to se if that bug occurs.
data[i] = 255;
}
}
return data;
}
[MenuItem, SubMenu("Data")]
public void ReadLots()
{
if (!VerifyConnectionRead())
return;
byte[] expectedData = MakeLotsData();
ReadLotsState state = new ReadLotsState(peer, expectedData);
state.data = new byte[expectedData.Length + 20];
ReadLotsStartNextRead(state);
console.Pause("Hit return to stop");
//lock (readLotsCurAr) {
// readLotsCurAr.
//}
}
IAsyncResult readLotsCurAr;
private void ReadLotsStartNextRead(ReadLotsState state)
{
if (state.numCompletedSynchronously > ReadLotsState.MaxCompletedSynchronously) {
// (There's lots of pending data and thus) We've CompletedSynchronously
// *many* times, so there's a danger of stack overflow
// (BeginRead->callback->BeginRead->callback->BeginRead->callback->...),
// so start the next operation on a new thread.
WaitCallback dlgt = delegate(object stateP) {
ReadLotsState state0 = (ReadLotsState)stateP;
state.numCompletedSynchronously = 0;
ReadLotsStartNextRead(state);
};
ThreadPool.QueueUserWorkItem(dlgt);
return;
}
readLotsCurAr = state.peer.BeginRead(state.data, state.totalLen, state.data.Length - state.totalLen,
ReadLotsReadCallBack, state);
console.Write("-");
}
class ReadLotsState
{
public ReadLotsState(Stream peer, byte[] expectedData)
{
this.peer = peer;
this.expectedData = expectedData;
}
public Stream peer;
public byte[] data;
public int totalLen;
//
public byte[] expectedData;
//
public int numCompletedSynchronously;
public const int MaxCompletedSynchronously = 50;
}
void ReadLotsReadCallBack(IAsyncResult ar)
{
ReadLotsState state = (ReadLotsState)ar.AsyncState;
int readLen ;
try {
readLen = state.peer.EndRead(ar);
} catch (ObjectDisposedException) {
console.WriteLine("Connection was closed during ReadLots.");
console.WriteLine("???, hit return to continue.");
return;
}
console.Write(">{1} ({0}) ", readLen, state.totalLen + readLen);
ArraysEqual(state.expectedData, state.data, state.totalLen, readLen);
state.totalLen += readLen;
if (ar.CompletedSynchronously)
++state.numCompletedSynchronously;
else
state.numCompletedSynchronously = 0;
if (state.totalLen == state.expectedData.Length) {
console.WriteLine("got all!");
return;
}
//
if (readLen == 0) {
console.WriteLine("EoF, hit return to continue.");
return;
}
ReadLotsStartNextRead(state);
}
private void ArraysEqual(byte[] expected, byte[] actual, int offset, int count)
{
for (int i = 0; i < count; ++i) {
if (offset + i >= expected.Length) {
console.WriteLine("!! ({0}+{1}=>) {2} >= {3}",offset , i, (offset + i), expected.Length);
}
if (offset + i >= actual.Length) {
console.WriteLine("!! ({0}+{1}=>) {2} >= {3}", offset, i, (offset + i), actual.Length);
}
if (expected[offset + i] != actual[offset + i]) {
console.WriteLine("wrong at {0}+{1}={2}", offset, i, offset + i);
break;
}
}
}
//----
[MenuItem]
public void BluetoothRadio_GetAll()
{
BluetoothRadio_GetAll__();
}
BluetoothRadio[] BluetoothRadio_GetAll__()
{
BluetoothRadio[] list = BluetoothRadio.AllRadios;
if (list == null)
console.WriteLine("AllRadios returned null!!!");
else if (list.Length == 0)
console.WriteLine("AllRadios returned empty list.");
int i = 1;
foreach (BluetoothRadio r in list) {
console.WriteLine("{0}) {1}", i, DumpBluetoothRadio(r));
++i;
}
return list;
}
[MenuItem]
public void BluetoothRadio_GetPrimary()
{
BluetoothRadio r = BluetoothRadio.PrimaryRadio;
if (r == null)
console.WriteLine("PrimaryRadio returned null.");
else
console.WriteLine(DumpBluetoothRadio(r));
}
private static string DumpBluetoothRadio(BluetoothRadio radio)
{
if (radio == null)
throw new ArgumentNullException("radio");
using (StringWriter wtr = new StringWriter()) {
RadioMode mode = radio.Mode;
// Warning: LocalAddress is null if the radio is powered-off.
wtr.WriteLine("Radio, address: {0:C}", radio.LocalAddress);
wtr.WriteLine("Mode: " + mode.ToString());
wtr.WriteLine("Name: " + radio.Name
+ ", LmpSubversion: " + radio.LmpSubversion);
wtr.WriteLine("ClassOfDevice: " + radio.ClassOfDevice.ToString()
+ ", device: " + radio.ClassOfDevice.Device.ToString()
+ " / service: " + radio.ClassOfDevice.Service.ToString());
wtr.WriteLine("Software: {0}, Hardware: {1}, status: {2}",
radio.SoftwareManufacturer, radio.Manufacturer, radio.HardwareStatus);
wtr.WriteLine("Remote: '{0}'", radio.Remote);
return wtr.ToString();
}
}
//----
#if TEST_EARLY
[MenuItem, SubMenu("BtLsnr")]
public void WidcommHackListen()
{
BluetoothAddress addr = BluetoothAddress.None;
//BluetoothAddress addr = console.ReadBluetoothAddress("Server's local BluetoothAddress");
Guid svcClass = BluetoothService.WapClient;
console.WriteLine("Default UUID : {0}", svcClass);
Guid? inputGuid = console.ReadOptionalBluetoothUuid("UUID");
if (inputGuid.HasValue)
svcClass = inputGuid.Value;
int? port = console.ReadOptionalInteger("Port number");
//
BluetoothEndPoint rep;
if (port == null)
rep = new BluetoothEndPoint(addr, svcClass);
else
rep = new BluetoothEndPoint(addr, svcClass, port.Value);
console.WriteLine("Connecting to: {0}:{1}:{2}", rep.Address, rep.Service, rep.Port);
//
InTheHand.Net.Bluetooth.Widcomm.WidcommBluetoothListener lsnr
= new InTheHand.Net.Bluetooth.Widcomm.WidcommBluetoothListener();
lsnr.Construct(rep);
lsnr.Start();
BluetoothClient conn = lsnr.AcceptBluetoothClient();
peer = conn.GetStream();
s_cli = new WeakReferenceT<BluetoothClient>(conn);
}
#endif
[MenuItem, SubMenu("GC")]
public void RunFinalizersAfterGc()
{
RunFinalizersAfterGc_();
}
public static void RunFinalizersAfterGc_()
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
[MenuItem, SubMenu("GC")]
public void RunGc()
{
RunGc_();
}
public static void RunGc_()
{
GC.Collect();
}
//----------
[MenuItem, SubMenu("OBEX")]
public void ObexWebRequest()
{
string addr = console.ReadLine("Address (IrDA / TCP/IP; hit return for BT)");
if (addr.Length == 0) {
BluetoothAddress addrB = console.ReadBluetoothAddress("Target Bluetooth device");
addr = addrB.ToString();
}
int? contentLen = console.ReadOptionalInteger("How much content (default ~60 bytes)");
if (contentLen == null)
contentLen = 60;
//NOT on NETCF!
// UriBuilder bldr = new UriBuilder();
// bldr.Scheme = "obex";
// bldr.Path = "/obexpush1.txt";
// bldr.Host = addr.ToString();
Uri uri = new Uri(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}://{1}{2}",
"obex", addr, "/obexpush1.txt"));
ObexWebRequest req = Create_ObexWebRequest(uri);
using (Stream content = req.GetRequestStream()) {
// Using a StreamWriter to write text to the stream...
using (TextWriter wtr = new StreamWriter(content)) {
int i=0;
while (content.Length < contentLen) {
++i;
wtr.WriteLine("Hello World GetRequestStream {0}",
// Write the time to the first line
i == 1 ? DateTime.Now.ToString() : i.ToString());
wtr.Flush(); // push through to stream
}
// Set the Length header value
req.ContentLength = content.Length;
}
}
console.WriteLine("Calling GetResponse with " + req.ContentLength + " bytes of content...");
ObexWebResponse rsp = (ObexWebResponse)req.GetResponse();
console.WriteLine("Response Code: {0} (0x{0:X})", rsp.StatusCode);
}
[MenuItem, SubMenu("OBEX")]
public void ObexWebRequest_GET()
{
string addr = console.ReadLine("Address (IrDA / TCP/IP; hit return for BT)");
if (addr.Length == 0) {
BluetoothAddress addrB = console.ReadBluetoothAddress("Target Bluetooth device");
addr = addrB.ToString();
}
string path = console.ReadLine("Path");
Uri uri = new Uri(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}://{1}/{2}",
"obex-ftp", addr, path));
console.WriteLine("Using URL: '{0}'", uri);
ObexWebRequest req = new ObexWebRequest(uri);
req.Method = "GET";
ObexWebResponse rsp = (ObexWebResponse)req.GetResponse();
console.WriteLine("Response Code: {0} (0x{0:X})", rsp.StatusCode);
using (Stream rspData = rsp.GetResponseStream()) {
StreamReader rdr = new StreamReader(rspData);
console.WriteLine("data, first line: '{0}'", rdr.ReadLine());
}
}
[MenuItem, SubMenu("OBEX")]
public void ObexListener()
{
m_lsnrStop = false;
Interlocked.Exchange(ref m_lsnrId, 0);
ObexListener lstnr = null;
ObexTransport? proto = null;
while (lstnr == null) {
int? i = console.ReadOptionalInteger("Which ObexListener transport: 1. Bluetooth, 2. IrDA, 3. TCP/IP");
if (!i.HasValue || i.Value == 1) {
proto = ObexTransport.Bluetooth;
lstnr = Create_ObexListener_Bluetooth();
} else {
while (!proto.HasValue) {
switch (i) {
case 2:
proto = ObexTransport.IrDA;
break;
case 3:
proto = ObexTransport.Tcp;
break;
default:
// (No Trace.Fail on NETCFv2)
Trace.Assert(false, "invalid input: " + i);
break;
}
}
lstnr = new ObexListener(proto.Value);
}
}
console.WriteLine("Created {0} ObexListener.", proto);
lstnr.Start();
console.WriteLine("OBEX listening");
int? count = console.ReadOptionalInteger("How many acceptors threads? (1 by default)");
if (count == null) {
count = 1;
}
console.WriteLine("Starting acceptor...");
for (int i = 0; i < count; ++i) {
ThreadPool.QueueUserWorkItem(ObexListener_Worker, lstnr);
}
try {
console.Pause("Hit return to continue; and close listener");
} finally {
m_lsnrStop = true;
lstnr.Stop();
}
}
private volatile bool m_lsnrStop;
private int m_lsnrId;
void ObexListener_Worker(object state)
{
int id = Interlocked.Increment(ref m_lsnrId);
while (true) {
ObexListener lstnr = (ObexListener)state;
if (m_lsnrStop || !lstnr.IsListening) {
break;
}
ObexListenerContext ctx = null;
try {
ctx = lstnr.GetContext();
if (ctx == null) {
console.WriteLine("{0}: OBEX null context!", id);
continue;
}
console.WriteLine("{0}: OBEX accepted lContext", id);
ObexListenerRequest req = ctx.Request;
console.WriteLine("{0}: OBEX lRequest url: {1}", id, req.RawUrl);
} catch (Exception ex) {
console.WriteLine("{0}: OBEX ctx/req fault: {1}", id, ex);
}
ctx = null;
}//while
}
//--------
#if TEST_EARLY
[MenuItem, SubMenu("Security etc")]
public void SetPain()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Address");
string passphrase = console.ReadLine("Passphrase");
using (BluetoothClient cli = new BluetoothClient()) {
InTheHand.Net.Bluetooth.Widcomm.BOND_RETURN_CODE ret = cli.WidcommHack__SetPinX(addr, passphrase);
console.WriteLine("Bond returned: {0} = 0x{1:X}", ret, (int)ret);
}
}
#endif
[MenuItem, SubMenu("Security etc")]
public void PairRequest()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Address");
string passphrase = console.ReadLine("Passphrase");
if (string.IsNullOrEmpty(passphrase)) {
bool makeNull = console.ReadYesNo("Do you want to use a null/Nothing passphrase", true);
passphrase = makeNull ? null : string.Empty;
}
InTheHand.Net.Bluetooth.Factory.IBluetoothSecurity sec
= Get_BluetoothRadio().StackFactory.BluetoothSecurity;
bool ret = sec.PairRequest(addr, passphrase);
console.WriteLine("PairRequest returned: {0}", ret);
}
[MenuItem, SubMenu("Security etc")]
public void RemoveDevice()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Address");
bool ret = BluetoothSecurity.RemoveDevice(addr);
console.WriteLine("RemoveDevice returned: {0}", ret);
}
//--------
[MenuItem, SubMenu("MultiStack")]
public void ListenerOnStack1ClientOnStack2()
{
BluetoothRadio[] radios = BluetoothRadio_GetAll__();
Debug.Assert(radios != null, "Should't return null!");
if (radios.Length < 2) {
console.WriteLine("Fewer that two radios were found ({0}).", radios.Length);
return;
}
//
ListenerOnStackAClientOnStackB(radios[0], radios[1]);
}
[MenuItem, SubMenu("MultiStack")]
public void ListenerOnStack2ClientOnStack1()
{
BluetoothRadio[] radios = BluetoothRadio_GetAll__();
Debug.Assert(radios != null, "Should't return null!");
if (radios.Length < 2) {
console.WriteLine("Fewer that two radios were found ({0}).", radios.Length);
return;
}
//
ListenerOnStackAClientOnStackB(radios[1], radios[0]);
}
public void ListenerOnStackAClientOnStackB(BluetoothRadio radioLsnr, BluetoothRadio radioCli)
{
BluetoothListener lsnr = radioLsnr.StackFactory.CreateBluetoothListener(BluetoothService.Wap);
BluetoothClient conn = null;
BluetoothClient cli = null;
try {
lsnr.Start();
#if APM_LSNR
IAsyncResult arLsnr = lsnr.BeginAcceptBluetoothClient(MiscCallback, "ListenerOnStack1ClientOnStack2");
#else
ManualResetEvent accepted = new ManualResetEvent(false);
WaitCallback dlgt = delegate(object state) {
BluetoothListener lsnr_ = (BluetoothListener)state;
conn = lsnr_.AcceptBluetoothClient();
accepted.Set();
};
conn = null;
ThreadPool.QueueUserWorkItem(dlgt, lsnr);
#endif
BluetoothEndPoint lep = lsnr.LocalEndPoint;
console.WriteLine("Listener active on SCN: {0}", lep.Port);
//
cli = radioCli.StackFactory.CreateBluetoothClient();
BluetoothEndPoint rep = new BluetoothEndPoint(radioLsnr.LocalAddress, BluetoothService.Empty, lep.Port);
console.WriteLine("Gonna connect to: {0}", rep);
console.Pause("Release to connect!");
cli.Connect(rep);
console.WriteLine("Client Connected to : '{0}' {1}", cli.RemoteMachineName, cli.RemoteEndPoint);
//
#if APM_LSNR
console.WriteLine("Lsnr.Accept.IsCompleted: {0}", arLsnr.IsCompleted);
conn = lsnr.EndAcceptBluetoothClient(arLsnr);
#else
console.WriteLine("waiting for Lsnr.Accept completion event.");
accepted.WaitOne();
Debug.Assert(conn != null, "Should have veen set by thread!");
#endif
console.WriteLine("All success");
console.Pause("Release to exit (and close both)");
} finally {
if (lsnr != null)
lsnr.Stop();
if (conn != null)
conn.Dispose();
if (cli != null)
cli.Dispose();
}
}
[MenuItem, SubMenu("MultiStack")]
public void ObexWebRequestMultiAsync()
{
BluetoothRadio[] radios = BluetoothRadio_GetAll__();
Debug.Assert(radios != null, "Should't return null!");
if (radios.Length < 1) {
console.WriteLine("No radios found.");
return;
}
//
List<BluetoothAddress> addrList = new List<BluetoothAddress>();
for (int i = 0; i < radios.Length;++i ) {
BluetoothAddress addr = console.ReadBluetoothAddress(
"Target device for radio #" + (i+1));
addrList.Add(addr);
}//for
bool bigSend = console.ReadYesNo("Send big (1MB) or small?", false);
byte[] bigBuf = null;
if (bigSend) {
bigBuf = new byte[1024 * 1024];
#if !NETCF
Array.ForEach(bigBuf, delegate(byte cur) { cur = (byte)'a'; });
#endif
}
List<IAsyncResult> arList = new List<IAsyncResult>(addrList.Count);
for (int i = 0; i < radios.Length; ++i) {
BluetoothAddress addr = addrList[i];
Uri uri = new Uri(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}://{1}{2}",
"obex", addr, "/obexpush1.txt"));
BluetoothPublicFactory factory = radios[i].StackFactory;
ObexWebRequest req = factory.CreateObexWebRequest(uri);
using (Stream content = req.GetRequestStream()) {
// Using a StreamWriter to write text to the stream...
if (bigSend) {
content.Write(bigBuf, 0, bigBuf.Length);
} else {
using (TextWriter wtr = new StreamWriter(content)) {
wtr.WriteLine("Hello World GetRequestStream");
wtr.WriteLine("Hello World GetRequestStream 2");
wtr.Flush();
// Set the Length header value
req.ContentLength = content.Length;
}
}
}
IAsyncResult ar = req.BeginGetResponse(null, req);
arList.Add(ar);
}//for
//
console.WriteLine("Waiting for all requests to complete...");
WaitAll(arList);
console.WriteLine("All requests completed...");
//
for (int i = 0; i < radios.Length; ++i) {
IAsyncResult cur = arList[i];
ObexWebRequest req = (ObexWebRequest)cur.AsyncState;
console.WriteLine("- - - #{1} - - -", null, (i + 1));
try {
ObexWebResponse rsp = (ObexWebResponse)req.EndGetResponse(cur);
console.WriteLine("#{1}. Response Code: {0} (0x{0:X})", rsp.StatusCode, (i + 1));
} catch (Exception ex) {
console.WriteLine("#{1}. Failed: {0}", ex, (i + 1));
}
}//for
}
//----
[MenuItem, SubMenu("Data")]
public void SetReadTimeout()
{
if (peer == null) {
console.WriteLine("no connection");
return;
}
console.WriteLine("ReadTimeout: {0}", peer.ReadTimeout);
int? to = console.ReadOptionalInteger("New value");
if (to.HasValue)
peer.ReadTimeout = to.Value;
}
[MenuItem, SubMenu("Data")]
public void SetWriteTimeout()
{
if (peer == null) {
console.WriteLine("no connection");
return;
}
console.WriteLine("WriteTimeout: {0}", peer.WriteTimeout);
int? v = console.ReadOptionalInteger("New value");
if (v.HasValue)
peer.WriteTimeout = v.Value;
}
//----
Stream _tcpConn;
[MenuItem]
public void TcpConnect()
{
string hostname = console.ReadLine("hostname");
int port = console.ReadInteger("port");
System.Net.Sockets.TcpClient cli = new System.Net.Sockets.TcpClient(hostname, port);
_tcpConn = cli.GetStream();
}
[MenuItem]
public void TcpClose()
{
if (_tcpConn != null) {
_tcpConn.Close();
}
_tcpConn = null;
}
//----
[MenuItem]
public void GetDeviceInfo()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Device Address");
BluetoothDeviceInfo device = Create_BluetoothDeviceInfo(addr);
console.WriteLine(DumpDeviceInfo(device));
}
[MenuItem]
public void SetServiceState()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Device Address");
Guid? svcClass = console.ReadOptionalBluetoothUuid("Service Class (default SPP)");
if (svcClass == null) svcClass = BluetoothService.SerialPort;
bool state = console.ReadYesNo("Enable/Disable the service", true);
BluetoothDeviceInfo device = Create_BluetoothDeviceInfo(addr);
console.WriteLine(DumpDeviceInfoBrief(device));
device.SetServiceState(svcClass.Value, state, true);
}
[MenuItem]
public void WidcommIsPresentConnected()
{
BluetoothAddress addr = console.ReadBluetoothAddress("Device Address");
InTheHand.Net.Bluetooth.Widcomm.RemoteDeviceState state
= new InTheHand.Net.Bluetooth.Widcomm.WidcommPlaying().FindIfPresentOrConnected(addr);
console.WriteLine("state: {0}", state);
}
//----
#if !NETCF
[MenuItem]
public void WmiSerialPorts()
{
const string Win32_SerialPort = "Win32_SerialPort";
#if false // Either work
console.WriteLine("Running query...");
System.Management.SelectQuery q = new System.Management.SelectQuery(Win32_SerialPort);
System.Management.ManagementObjectSearcher s = new System.Management.ManagementObjectSearcher(q);
#else
console.WriteLine("Running WMI query...");
System.Management.ManagementObjectSearcher s = new System.Management.ManagementObjectSearcher(
"SELECT DeviceID,PNPDeviceID FROM " + Win32_SerialPort);
#endif
console.WriteLine("Getting results...");
System.Management.ManagementObjectCollection list = s.Get();
console.WriteLine("Enumerating results...");
foreach (System.Management.ManagementBaseObject cur in list) {
object id = cur.GetPropertyValue("DeviceID");
object pnpId = cur.GetPropertyValue("PNPDeviceID");
console.WriteLine("DeviceID: {0} ", id);
console.WriteLine("PNPDeviceID: {0} ", pnpId);
console.WriteLine("");
}//for
//----
console.WriteLine("SerialPort.GetPortNames...");
string[] nameList = System.IO.Ports.SerialPort.GetPortNames();
console.WriteLine("SerialPort.GetPortNames: {0}",
string.Join(", ", nameList));
}
#endif
//----
[MenuItem, SubMenu("SOCKETS")]
public void TestsSocketsAndSockaddr()
{
Converter<bool, System.Net.Sockets.Socket> createSocket = delegate(bool unspecificProto) {
System.Net.Sockets.Socket s0;
if (unspecificProto)
s0 = new System.Net.Sockets.Socket(
AddressFamily32.Bluetooth, System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Unspecified);
else
s0 = new System.Net.Sockets.Socket(
AddressFamily32.Bluetooth, System.Net.Sockets.SocketType.Stream,
BluetoothProtocolType.RFComm);
return s0;
};
BluetoothEndPoint ep;
System.Net.Sockets.Socket s;
//
int step = 0;
console.WriteLine("#{0}, gonna createSocket(false)", ++step);
s = createSocket(false);
ep = new BluetoothEndPoint(
BluetoothAddress.None,
BluetoothService.ObexFileTransfer);
console.WriteLine("#{0}, gonna Bind", ++step);
// Bind None/FTP/None
try {
s.Bind(ep);
} catch (Exception ex) {
console.WriteLine(ex);
}
ep = new BluetoothEndPoint(
BluetoothAddress.Parse("12345679abcd"),
BluetoothService.ObexObjectPush);
console.WriteLine("#{0}, gonna Connect", ++step);
// Connect Foo/OPP/None
try {
s.Connect(ep);
} catch (Exception ex) {
console.WriteLine(ex);
}
//
console.WriteLine("#{0}, gonna createSocket(false)", ++step);
s = createSocket(false);
ep = new BluetoothEndPoint(
BluetoothAddress.None,
BluetoothService.ObexFileTransfer,
unchecked((Int32)0xF2345678));
console.WriteLine("#{0}, gonna Bind", ++step);
// Bind None/FTP/Bar
try {
s.Bind(ep);
} catch (Exception ex) {
console.WriteLine("Excepted failure");
console.WriteLine(ex);
}
//
ep = new BluetoothEndPoint(
BluetoothAddress.None,
BluetoothService.ObexFileTransfer,
0x45);
console.WriteLine("#{0}, gonna Bind", ++step);
// Bind None/FTP/Bar
try {
s.Bind(ep);
} catch (Exception ex) {
console.WriteLine(ex);
}
//
ep = new BluetoothEndPoint(
BluetoothAddress.Parse("12345679abcd"),
BluetoothService.Fax, 0x45);
console.WriteLine("#{0}, gonna Connect", ++step);
// Connect Foo/OPP/Bar
try {
s.Connect(ep);
} catch (Exception ex) {
console.WriteLine(ex);
}
//
console.WriteLine("#{0}, gonna createSocket(true)", ++step);
try {
s = createSocket(true);
} catch (System.Net.Sockets.SocketException ex) {
const int WSAEPROTOTYPE = 10041;
#if NETCF
if (ex.ErrorCode != WSAEPROTOTYPE)
throw;
#else
if (ex.SocketErrorCode != System.Net.Sockets.SocketError.ProtocolType)
throw;
#endif
Trace.Assert(ex.NativeErrorCode == WSAEPROTOTYPE);
console.WriteLine("(Somewhat) expected failure; how to get 'Unspecified' behaviour supported?");
console.WriteLine(ex);
}
}
//--------
[MenuItem]
public void RSSI_repeated()
{
console.WriteLine("Stack: {0}", Get_BluetoothRadio().SoftwareManufacturer);
BluetoothAddress addr = console.ReadBluetoothAddress("Address of device to read RSSI for");
bool doSdp = console.ReadYesNo("Do concurrent repeated SDP Query", true);
//
_quitRepeatRssiing.Reset();
try {
ThreadPool.QueueUserWorkItem(RepeatRssiing_ReadRssi, addr);
if (doSdp) { // Doing SDP queries to force forming a connection.
ThreadPool.QueueUserWorkItem(RepeatRssiing_DoSdp, addr);
}
console.WriteLine(null);
console.Pause("Continue to stop RSSI-ing");
} finally {
_quitRepeatRssiing.Set();
}
}
ManualResetEvent _quitRepeatRssiing = new ManualResetEvent(false);
void RepeatRssiing_ReadRssi(object state)
{
BluetoothAddress addr = (BluetoothAddress)state;
int delayMs = 1000;
BluetoothDeviceInfo info = Create_BluetoothDeviceInfo(addr);
int? lastRssi = null;
while (!_quitRepeatRssiing.WaitOne(delayMs, false)) {
int rssi = info.Rssi;
console.Write("r");
if (rssi != lastRssi) {
lastRssi = rssi;
console.WriteLine(null);
console.WriteLine("{0:T}: RSSI now: {1}", DateTime.Now, rssi);
}
}//while
}
void RepeatRssiing_DoSdp(object state)
{
Thread.Sleep(5000); // show rssi not available when not connected
//
BluetoothAddress addr = (BluetoothAddress)state;
int delayMs = 1000;
BluetoothDeviceInfo info = Create_BluetoothDeviceInfo(addr);
while (!_quitRepeatRssiing.WaitOne(delayMs, false)) {
ServiceRecord[] records = info.GetServiceRecords(BluetoothService.TcpProtocol);
console.Write("s");
}//while
}
//--------
[MenuItem]
public void RadioSetMode()
{
BluetoothRadio r = Get_BluetoothRadio();
if (r == null) {
console.WriteLine("No radio(?)");
return;
}
console.WriteLine("Radio stack is: {0}", r.SoftwareManufacturer);
int choice = console.ReadInteger("0. PowerOff, 1. Connectable, 2. Discoverable");
RadioMode mode = (RadioMode)choice;
bool doit = console.ReadYesNo("Set radio mode to: " + mode, true);
if (doit) {
r.Mode = mode;
}
}
//--------
[MenuItem, SubMenu("Data")]
public void CloseLinger()
{
if (!VerifyConnectionWrite())
return;
BluetoothClient cli = s_cli.Target;
if (cli == null) {
console.WriteLine("No BtCli to set LingerState on!.");
return;
}
cli.LingerState = new System.Net.Sockets.LingerOption(true, 30);
// Write until buffers full
List<IAsyncResult> arList = new List<IAsyncResult>();
byte[] buf = new byte[16 * 1024];
bool exitAfterNext = false;
while (true) {
IAsyncResult ar = peer.BeginWrite(buf, 0, buf.Length, MiscCallback, "BeginWrite");
arList.Add(ar);
console.Write(".");
if (exitAfterNext)
break;
if (!ar.IsCompleted) {
bool signalled = ar.AsyncWaitHandle.WaitOne(10000, false);
if (!signalled) {
exitAfterNext = true;
}
}
}//while
console.WriteLine("Did BeginWrite until full ({0} times).", arList.Count);
//
console.WriteLine("Now going to Close. Release receiver to not linger timeout.");
console.Pause("Continue to Close");
console.WriteLine("Closing at {0}", GetTime());
DateTime startT = DateTime.UtcNow;
try {
peer.Close();
string end = GetTime();
console.WriteLine("Close exited cleanly at {0} after {1}.", end, DateTime.UtcNow - startT);
} catch (Exception ex) { // We throw Exception currently!
string end = GetTime();
console.WriteLine("Close failed at {0} after {1} with: {2}", end, DateTime.UtcNow - startT, ex);
}
//
int i = 0;
console.Write("Write statuses (. or x, x=exception): ");
foreach (IAsyncResult cur in arList) {
if (!cur.IsCompleted) {
console.WriteLine("Write #{0} is not completed!", i + 1);
}
try {
peer.EndWrite(cur);
console.Write(".");
} catch (IOException) {
console.Write("x");
}
++i;
}//for
console.WriteLine(null);
console.WriteLine("Finished.");
}
//--------
[MenuItem]
public void HackShutdownAll()
{
InTheHand.Net.Bluetooth.Factory.BluetoothFactory.HackShutdownAll();
console.WriteLine("Done HackShutdownAll");
}
//--------
private string ToStringQuotedOrNull<T>(T obj)
{
if (obj == null)
return "(null)";
else
return obj.ToString();
}
string Exception_FirstLine(Exception ex)
{
using (StringReader rdr = new StringReader(ex.ToString())) {
return rdr.ReadLine();
}
}
}//class
}
|