Solved

RFCOMM: Windows Mobile 2003 - Virtual COM Port - ERROR_DEVICE_IN_USE

Posted on 2003-11-04
11
32,104 Views
Last Modified: 2013-12-14
I'm developing an application (Pocket PC 2003 / Windows Mobile 2003) which should establish a RFCOMM Bluetooth connection to a bluetooth-server-device. ( A serial interface for an older non-bluetooth version of this device already exists. PPC is the T-Mobile MDA )

So i checked the scanty microsoft documentation and found out, that it is possible to create a virtual com port with
RegisterDevice(L"COM", index, L"btd.dll", (DWORD)&pp).

With WSALookupServiceBegin(...) and WSALookupServiceNext(...) it was possible to detect the BT_ADDR needed for the PORTEMUPortParams (see above -> pp ) device parameter.

But RegisterDevice always fails with SystemError:ERROR_DEVICE_IN_USE (The device is in use by an active process and cannot be disconnected.) - Then i checked the "HKLM\drivers\Active" Key in my PPC registry and found out, that there is no service using COM 4, 5 or 6. But this Ports also generate this error message.

Interestingly enough the "btd.dll" is not yet loaded. So i guess my PORTEMUPortParams structure isn't the error source.

The sample source code supplied with Windows CE Evaluation Edition seems to do exactly the same.

Maybe I could have forgotten to implement several important gimmicks. Or maybe there is another way to connect with a RFCOMM bluetooth device.

Thanks in advance.

Here is the source (without catching any errors :)

/*+++++++++++Startup WSA+++++++++++++++++*/
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
WSAStartup( wVersionRequested, &wsaData );

/*+++++++++++++Search for my device++++++++++++++++*/
INT iResult = 0;
LPWSAQUERYSET pwsaResults;
DWORD dwSize = 0;
WSAQUERYSET wsaq;
HANDLE hLookup = 0;
memset (&wsaq, 0, sizeof(wsaq));
wsaq.dwSize = sizeof(wsaq);
wsaq.dwNameSpace = NS_BTH;
wsaq.lpcsaBuffer = NULL;

WSALookupServiceBegin(&wsaq, LUP_CONTAINERS, &hLookup);

union {
CHAR buf[5000];
SOCKADDR_BTH      __unused;
};
pwsaResults = (LPWSAQUERYSET) buf;
dwSize  = sizeof(buf);            
memset(pwsaResults,0,sizeof(WSAQUERYSET));
pwsaResults->dwSize      = sizeof(WSAQUERYSET);
pwsaResults->dwNameSpace = NS_BTH;
pwsaResults->lpBlob      = NULL;

WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults);
// Real device name is found ... pwsaResults->lpszServiceInstanceName;

/*+++++++++Now trying to register the virtual COM Port+++++++++++++++*/
PORTEMUPortParams pp;
memset (&pp, 0, sizeof(pp));
pp.channel = 0;
pp.flocal = false;
pp.device = reinterpret_cast<_SOCKADDR_BTH*>(pwsaResults->lpcsaBuffer->LocalAddr.lpSockaddr)->btAddr;
//the detected BT_ADDR
memcpy(&pp.uuidService, &CLSID_NULL, sizeof(GUID));
pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB;
int port = 4; //or anything else like 1..4,5 or 6..9 | Limit is 9 i think
HANDLE bth = RegisterDevice  (L"COM", port, L"btd.dll", (DWORD)&pp));

/*++++++++the result+++++++++++++++++++*/
//bth == 0
//GetLastError () == ERROR_DEVICE_IN_USE :(
0
Comment
Question by:tstwk
11 Comments
 
LVL 3

Expert Comment

by:cindy_k
ID: 9680833
Here is some code I use to Register a com port to use with Bluetooth.
I noticed you Channel is 0, try setting it to 1.
You can discover the Channel by Querying for information on the RFCOMM Serial Service but doing full SDP is a pain.

You are correct the limit is 9 for com ports on a CE device.
The GetBA function I call is from a Sample from Microsoft Platform builder.
I included it so you can look at it.

If this function succeeds you should be able to open the Com Port and communicate over it.
This function will not check to see if the device you are connecting to exists, it just sets up the comm port.
When you go to open the Comm Port if the device is out of range, suspended, whatever the CreateFile call will fail.

Hope this helps,
Cynthia

BOOL RegisterPort(void)
{
      PORTEMUPortParams pp;
      int nIndex;
      WCHAR sBA[13];
      int nChannel;
      WCHAR sChannel[4];

      GetWindowText(GetDlgItem(g_hDlg,TXT_CHANNEL),sChannel,3);
      swscanf(sChannel,L"%d",&nChannel);

      WCHAR sIdx[2];
      int idx;


      //*************************************************************************
      //*************************************************************************
      //*************************************************************************
      // This section demonstrates how to create a BT virtual COM port
      //  Begin

      memset (&pp, 0, sizeof(pp));                        // Clear the PORTEMUPortParams  structure.
//      pp.channel = 6;      //Printer                              // Set to either an explicit server
      pp.channel = nChannel;                              //  channel, or, for a server
                                                //  application that wants the
                                                //  server channel to be autobound,
                                                //  to RFCOMM_CHANNEL_MULTIPLE.
//      pp.channel = RFCOMM_CHANNEL_MULTIPLE;

      pp.flocal = FALSE;                                    //  Set to FALSE for a client port that
                                                //   is used to creating outgoing connections.

      GetBA(_T("0002C710F63E"), &pp.device);            // Using Static BTADDR

      nIndex = 7;      // This must be the same as the COM port number.

      // For devices that expose the stream interface, the drivers are
      // DLL files. Each driver is initialized by a call to the RegisterDevice
      // function. The Device Manager calls this function on behalf of the
      // driver. However, applications can load their own special-purpose stream
      // interface, in which case they also call this function to register the driver.

      h = RegisterDevice(_T("COM"), nIndex, _T("btd.dll"), (DWORD)&pp);


      if (h != NULL)
      {
            bRegister =  TRUE;
      }
      else
            bRegister =  FALSE;

      SetCursor(LoadCursor(NULL, NULL));                  // Clear the wait cursor
      
      return bRegister;
}
/******************************************************************************
      FUNCTION:      GetBA
      PROTOTYPE:  int GetBA (WCHAR *pp, BT_ADDR *pba)
      PURPOSE:      Form the BDADDR in a way the PORTEMUPortParams structure
                        understands.
******************************************************************************/
int GetBA (WCHAR *pp, BT_ADDR *pba)
{
      // Bump pointer through any leading spaces
      while (*pp == ' ')
            ++pp;

      for (int i = 0 ; i < 4 ; ++i, ++pp)
      {
            if (!iswxdigit (*pp))
                  return(FALSE);

            int c = *pp;
            if (c >= 'a')
                  c = c - 'a' + 0xa;
            else if (c >= 'A')
                  c = c - 'A' + 0xa;
            else c = c - '0';

            if ((c < 0) || (c > 16))
                  return(FALSE);

            *pba = *pba * 16 + c;
      }

      for (i = 0; i < 8 ; ++i, ++pp)
      {
            if (!iswxdigit (*pp))
                  return(FALSE);

            int c = *pp;
            if (c >= 'a')
                  c = c - 'a' + 0xa;
            else if (c >= 'A')
                  c = c - 'A' + 0xa;
            else c = c - '0';

            if ((c < 0) || (c > 16))
                  return(FALSE);

            *pba = *pba * 16 + c;
      }

      if ((*pp != ' ') && (*pp != '\0'))
            return(FALSE);
      else
            return(TRUE);
}
0
 

Author Comment

by:tstwk
ID: 9685144
Hello Cynthia,

thanks for the fast reply. Unfortunately it seems that there is no great deviation from my code, unless my BT_ADDR causes the problem. Nonetheless I tested yours, but the result was the same. I also took the sequence out of an additional thread.

>I noticed you Channel is 0, try setting it to 1.
I've already tried every channel with every port. :(

(snip...)
for(pp.channel = 0; pp.channel <= 8; ++pp.channel)
        for(int port = 1; port <= 9; ++port)
            if(bth = RegisterDevice  (L"COM", port, L"btd.dll", (DWORD)&pp))
               return bth;
return INVALID_HANDLE_VALUE;
(...snap)

>This function will not check to see if the device you are connecting to exists, it just sets up the comm port.
>When you go to open the Comm Port if the device is out of range, suspended, whatever the CreateFile call will fail.

So only CreateFile should be interested in BT_ADDR. The BT_ADDR I have detected through WSALookupServiceNext is 0x2c724d6f7. It resembles the BT_ADDR of your sample. The device has a PIN code, but this should have nothing to do with virtual com ports?!?

Is there a way, to find out more about the systems comm ports?
Is HKLM\drivers\Active the only hint, who could occupy the ports?
Is there anything I could have forgotten to initialize?
I am debugging over ASync - might this be a problem?

Regards,
Tom
0
 
LVL 3

Expert Comment

by:cindy_k
ID: 9687490
You're right about the Channel. It shouldn't be an issue when Registering. Sorry about that.
When your registering the COM port, you don't even need the device in the area, since it doesn't try to reach out until you go to open the com port.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\2] <- The bluetooth hardware com port is in this registry setting.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\HCI] <- And this one.

ActiveSync shouldn't effect registering the Virtual Com Port.

This code lists the Active Devices in the system.. Microsoft has a new function to use also called RequestDeviceNotifications.  Its more complicated to use,
so I used this one. It accuractly returned the devices in used on my system.

#include <devload.h>

int WINAPI WinMain(      HINSTANCE hInstance,
                              HINSTANCE hPrevInstance,
                              LPTSTR    lpCmdLine,
                              int       nCmdShow)
{
       // TODO: Place code here.


      WCHAR szDevList[800];
      DWORD dwBuffer = 800;
      DWORD Return;

      //This function returns a list of the active device file names currently present in the file system.
      //Calling RequestDeviceNotifications with DEVCLASS_STREAM_GUID supersedes this function.

                Return = EnumDevices((WCHAR*)&szDevList, &dwBuffer);
                //The String returned has q List of null-terminated strings. The list terminates with two consecutive null characters, one terminating the last entry in the
                // list and an additional null, for example, "COM1:\0COM2:\0PGR1:\0\0".


      switch(Return)
      {
      case ERROR_SUCCESS: // The function returned successfully.
      {
            WCHAR szReformat[1500];
            DWORD Start = 0;

                                //Parse the Returned list so I can see it in a MessageBox.
            for(DWORD x = 0; x < dwBuffer; x++)
            {
                  if(szDevList[x] == '\0')
                  {
                        if(Start == 0)
                        {
                              wsprintf(szReformat,L"%s:",szDevList);
                              Start = x+1;
                        }
                        else if(Start == x)
                        {
                              Start = x+1;
                        }
                        else
                        {
                        wsprintf(szReformat,L"%s%s:",szReformat,szDevList+Start);
                        Start = x+1;
                        }
                  }
            }

            MessageBox(NULL,szReformat,L"COM Data",MB_OK);
      }
      break;
      case ERROR_INSUFFICIENT_BUFFER: // The lpszDevList buffer was not big enough to hold any entries; lpBufLen will contain the required size.
            MessageBox(NULL,L"Insufficient Buffer",L"COM Data",MB_OK);
      break;
      case ERROR_INVALID_PARAMETER: // The lpBufLen parameter was NULL.
            MessageBox(NULL,L"Invalid Parameters", L"COM Data",MB_OK);
      break;
      case ERROR_MORE_DATA: // The lpszDevList buffer was not big enough to hold the complete list of active devices; lpBufLen will contain the required size.
            MessageBox(NULL,L"ERROR MORE DATA",L"Com Data",MB_OK);
      break;
      case ERROR_NO_MORE_DEVICES:
            MessageBox(NULL,L"No More Devices",L"Com Data",MB_OK);
      break;
      }

      return 0;
}





0
 

Author Comment

by:tstwk
ID: 9692644
The serial devices return are COM 1,2,3,6,8 and 9. So there are "free" Ports.
BUT.... the key [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\2] you mentioned above is absend!

Only [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\1] with bthusb.dll and [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\3] with bthcsr.dll (concerning COM6).

I think this is a pretty obvious error. But unfortunately I found out nothing about this registry key. Would you be so kind to give me further informations or a list of sources about my absend [...\BuildIn\2] registry key, so i have the chance to find out more about it. Just to reproduce the problem. Is it the btd.dll mentioned in [...BuiltIn\2]?
Am I right that the hardware manufacturer is responsible for the development (DLLs and registry-settings) of its Win CE Platform?

If I have a blade of grass to hang on, I'll close this question with a clear conscience : )
0
 
LVL 3

Expert Comment

by:cindy_k
ID: 9695700
>>Am I right that the hardware manufacturer is responsible for the development (DLLs and registry-settings) of its Win CE Platform?
Partially.  It depends of whether the Radio is embedded into the device or not. If its embedded than the Device manufacturer would be the one responsible for drivers and registry settings. If you are adding a bluetooth compact flash card, then the card manufacturer would be responsible.

Can I ask what Bluetooth card you are using?
For example, I know that Socket offers an SDK to go with their card but they don't use the Microsoft Stack for their card.

I am currently working on a device that my company is building, we have our own internal Bluetooth chipset and we are using the Microsoft Stack. I got those registry settings from that device.

I have a CE device here with a Socket BT compact flash card in it.  I just looked at it's registry settings and they are different.
Because it's in the Compact Flash slot it doesn't have a Serial port assigned to it, like my other device does.
It has this setting but doesn't have a 2 or 3.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\1]

I can register a port with the Socket card, but I am having trouble opening the com port. Of course I can create the connection with the Socket SDK with no problem.
They use the Draker Stack.

I just looked into the IPAQ's I have with Bluetooth in them and they use the WidComm stack. You have to get the SDK to use that stack from them. Looks like they are charging for it.  www.widcomm.com
I can't register a com port on my IPAQ for bluetooth either.  I'm guessing they do this so you are forced to buy their SDK.

Hope this helps some.
Cynthia


0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:tstwk
ID: 9701029
Bluetooth is integrated in the T-Mobile MDA II ... http://msmobiles.com/article.php/54.html (most of the articles I found were german) It seems to have features like the IPaqs. Addionately it has a fantastic camera feature (and is a cell-phone : ). The IPaq (Bluetooth-PPC) might be an alternative for us, but if the problem persists it wouldn't make much sense.

Is it possible to use the wsa sockets on the IPqaw without using the WidComm stack? The thing I don't understand is - Windows Mobile 2003 has a stack for Virtual COM Ports and the manufacturer doesn't implement it, so that no generic software can use it?!?

I have already contacted the manufacturer, but still no answer. Maybe the MDA II has third party bluetooth stuff, too. If telekom answers, I'll know.

Do you have any further ideas?

The device you are working on might be an alternative, too... Currently we are selling yakumo deltas with leica disto pro 4 lasermeasurement devices. But the cable is disturbing while working with the laser device... http://www.mobilaufmass.com/Mobilaufmass/Das_Mobilaufmass_im_Einsatz/Steuerung.htm (unfortunately the site is german)

Thanks for your endurance.

Thomas
0
 
LVL 3

Accepted Solution

by:
cindy_k earned 500 total points
ID: 9703896
Unfortunately I don't know the widcomm stack so I don't know if you can get around buying their SDK.

The device with the embedded bluetooth that I am using comes from Symbol Technologies, Inc. but is currently not for sale. I am doing some evaluation development work on it.

However, Symbol sells this device:
 http://www.symbol.com/products/mobile_computers/mobile_ppt8800_ppc2003.html
It has a Socket Bluetooth radio in it and I know Symbol will supply the SDK to their customers, so they will be able to write their own code to use the radio.

It's no problem.  I understand such frustration with new product. Documentation? What documentation!?!
Trust me, you don't want to write an Service Discovery App using the Microsoft Stack. It was difficult, because the documentation provided with the APIs was extremely lacking and wrong.

Good Luck!!
Cynthia
0
 
LVL 2

Expert Comment

by:cerebralpc
ID: 10492484
Hi tstwk,
You wrote..

"Is it possible to use the wsa sockets on the IPaq without using the WidComm stack? The thing I don't understand is - Windows Mobile 2003 has a stack for Virtual COM Ports and the manufacturer doesn't implement it, so that no generic software can use it?!? "


Do you ever resolve this issue?
I'm currently programming an application for an IPaq 2210 and although I've managed to get 1 device connected and transfering data to the IPaq I actaully need to connect 2 Bluetooth devices.  Therefore I really need to create VIRTUAL ports however as you suggest VIRTUAL ports don't come with this stack - sigh.

Another issue wsa that I had to set the IPaq as the master device - although the connection would appear to be made if the IPaq was the slave no data would actually be sent.

I've emailed the maker widcomm.com but never got satisfactory replys.
0
 

Expert Comment

by:Synth2
ID: 11220254
cindy_k

Your application needs both Bluetooth devices to be paired or it's not necessary because you implement an SDP query? maybe it's implemented by default?
I have a Dell Axim X3 and i want to make a connection between it and a Pc.
Dell Axim X3 Bluetooth hardware manufacturer is Widcomm.Won't I be able to create VIRTUAL COM from my Pocket PC if i don't get the Widcomm SDK?
0
 

Author Comment

by:tstwk
ID: 11220417
We found out, that the RFCOMM stuff simply doesn't work on the MDA II. It's a himalaya device, all of these devices are showing the same peculiarity.
They send us 3 different version of their PPC, but without any progress within the implementation of RFCOMM. There's also a logical error in the user interface: You can "find and connect" the device to the pocket pc in Windows Mobile 2003 and you can set bluetooth com-ports (COM4 output, COM5 input), but there is no setting to combine the com-port with the device?!?

Because of this, you can never connect these Pocket PCs to a RFOMM device (GPS etc.). *g*

Dell Axim X3 question: Now we are using the WIDCOMM stack (only MFC-support I think) for RFCOMM, which has its errors, but with some workarounds you can wangle it. In my opinion the WIDCOMM Support is miserable.
I'm relatively sure, that without buying the WIDCOMM stack you won't be able to connect the devices. But maybe it's possible... There are many extra features for searching devices etc. int the stack, so that the users do not need to establish the connection in the widcomm settings.
Because of some errors the newer WIDCOMM PPCs have revised SDK-DLLs in their ROM, maybe you could use them (BtCoreIf.dll BtSdkCE30.dll)?!? Normally you must install them yourself. It is hard enough with the mfc classes. But it's not, that you pay for nothing...

0
 

Expert Comment

by:myopic
ID: 11299287
Having similar trouble on WinCE 4.2.  I haven't written my own app, just used the sample ones that came with it.  I may be able to shed some light on a little of what was said before.

The registry settings under
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Bluetooth\Transports\BuiltIn\]
Are for bluetooth transports.  The transport is the way the Host (WinCE) talks to the bluetooth device.  Eg. Serial/USB/PCMCIA etc.  They are at a lower level then what is trying to be done here.

I've heard that it's possible to get this working but I can't find any resources on the net anywhere.

0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Need WiFi? Often, there are perfectly good networks that don't have WiFi capability - and there's a need to add it.  - Perhaps you have an Ethernet port into a network but no WiFi nearby. - Perhaps you have a powerline extender and no WiFi at the…
For Sennheiser, comfort, quality and security are high priority areas. This paper addresses the security of Bluetooth technology and the supplementary security that Sennheiser’s Contact Center and Office (CC&O) headsets provide.  
This Micro Tutorial will show you how to maximize your wireless card to its maximum capability. This will be demonstrated using Intel(R) Centrino(R) Wireless-N 2230 wireless card on Windows 8 operating system.
Viewers will learn how to connect to a wireless network using the network security key. They will also learn how to access the IP address and DNS server for connections that must be done manually. After setting up a router, find the network security…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now