Delay Required before getting Stream

Topics: Bluetooth - Microsoft, Bluetooth - Stonestreet
Jan 11, 2013 at 2:01 PM

I had some issues connecting to a Zebra 420T printer lately on Motorola Devices (Where I paired through the OS and sent data over COM Port).  All of their new ones without the StoneStreet Stack won't connect.  On ones with it I used a registry hack to enable StoneStreet, but fewer and fewer are having that ability.  So, I looked at your solution to print direct instead of using a COM port on Win Mobile and Desktop Windows (XP has issues keeping the same port on different usernames too which got annoying).

Upon using the library it still had some issues too with various not a socket errors and services claiming to not exist, etc.  I found though that sometimes it would print fine then the next 5-6 times wouldn't.  Biggest breakthrough though was while debugging it always printed.  The Code Examples were a great start but missing one important piece- a delay waiting for the connection before getting the stream.  Code is below for anyone else having issues (Text in txtPrinter is populated by scanning a DataMatrix barcode of Printer Bluetooth MAC Address):

 

 

private bool SendToPrinter(string printString)
{
    try
    {
        BluetoothAddress addr = BluetoothAddress.Parse(txtPrinter.Text);
        Guid serviceClass = BluetoothService.SerialPort;
        var client = new BluetoothClient();
        client.SetPin(addr, "1234");
        client.Connect(addr, serviceClass);
        DateTime abortTime = DateTime.Now.AddSeconds(20);
        while (!client.Connected)
        {
            if (DateTime.Now >= abortTime)
            {
                MessageBox.Show("Connection Timeout");
                client.Close();
                return false;
            }
            Application.DoEvents();
        }
        Stream btStream = client.GetStream();
        btStream.Write(Encoding.ASCII.GetBytes(printString), 0, Encoding.ASCII.GetBytes(printString).Length);
        btStream.Flush();
        btStream.Close();
        client.Close();
    }
    catch
    {
        return false;
    }
    return true;
}

 

 

Developer
Jan 12, 2013 at 12:14 PM

Glad to hear you've got it working. I'm a fan of Sockets rather than COM ports as you probably have read. :-)

I'm intrigued by the workaround you need however. I'll keep it in mind for other people however. Can you confirm that this is required with the Microsoft stack on WM? (Or also SSO on WM?)

On MSFT stacks (desktop and WM/CE) our BluetoothClient and the .NET's NetworkStream are very simple wrappers around .NET's Socket and thus around the native socket/WSASocket API. WSAConnect should not return unless the socket is connected and thus members get_Connected and GetStream should be usable immediately -- with get_Connected certainly being true immediately. But you find that's not the case...

Jan 14, 2013 at 3:38 PM
Edited Jan 14, 2013 at 3:44 PM

Devices I used were Motorola MC55, MC65, and MC75.  I started out with the MC55 that was set to use StoneStreet.  When having issues from not using the delay I had switched to Microsoft's and still had issues.  I then noticed it printing in debug but didn't put the two together yet.  I just figured the MC55 had some issues, so went on to the MC65 that only has Microsoft's Stack.  It had the same problems and I noticed it printing in debug again and that the only difference was I stepped through and it made a delay.  A lightbulb then went off and I added the delay before the stream since most of the errors mentioned no socket and such.  Sometimes StoneStreet still had hiccups- I think another thread mentioned the same error and it had to do with multiple connections and it only being able to do one.

 

With the Devices lately going away from StoneStreet (MC65 and ES400 can't switch and half the MC75s we get/got can't switch)  I switched them all to Microsoft and verified it works with the delay/wait and didn't without it (Maybe 1 in 10 connections would work).  It could be the combination of the devices and the printer making a special case too.  These printers are annoying and they keep sending them from Mfg without a PIN which only works on StoneStreet and old Microsoft.  I have to connect to every one of the things we sell to customers to configure them.  Tiny little MAC address barcode on them won't scan either and I have to make my own.

Developer
Jan 15, 2013 at 8:05 PM

OK cool. Maybe well be some interaction between these sorts of devices.

I don't want you to have to spend much more time on it. But I wonder firstly without the delays do you remember if the failure occurs at the Connect, GetStream, or at the Read/Write of the NetworkStream. And, related, does the delay work if moved to after the GetStream.  Anyway enough probably! :-) I'm just really surprised/confused that client.Connected is false on return from Connect. :-,(

Jan 15, 2013 at 8:17 PM
Edited Jan 15, 2013 at 8:17 PM

client.GetStream() was the failure point, that is why I put the delay before it.

Since it is a while loop the condition is checked beforehand and having it made a difference, so I'm guessing it at least loops once.

I had tried just adding Application.DoEvents() only between them and it still failed, so it probably loops more than once.