Author Topic: Win XP: Radio name differs in wclClient.BluetoothParams and wclBluetoothDevice  (Read 31596 times)

Flominator

  • Guest
I have a problem with one of our devices, but only on Windows XP (yes, I'm aware that it's not supported by Microsoft anymore, but I'm hoping for some knowledge/interest anyway)

Currently using WCL 6.11.4.0 but updating to trial version of 6.14.1.0 didn't change a thing.

OnDiscoveryComplete returns a wclBluetoothDevice with name "COMPUTERNAME". As learned some days ago, I store device and radio of the wclBluetoothDiscoveryCompleteEventArgs by creating a new wclBluetoothDevice and wclBluetoothRadio and perform assign() on the e objects. Then I store those two variables in a struct as a member variable on my tab pages.

Some seconds later the radio is named "al Port". Do you have any hint, what I'm doing wrong?

Thanks,

Flo



Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Hi,

wclBluetoothDevice and wclBluetoothRadio are absolutely different objects. wclBluetoothDevice represents a remote Bluetooth enabled device. wclBluetoothRadio represents a local Bluetooth Radio module. And of course they will have different names.

Also I do not recomend to store any wclBluetoothRadio information and use EnumRadios instead each time you need to find a local Radio (at least you can call EnumRadios when your application run first time then use this Radio in your work. However it can be changed since you remove/replug dongle so after that you have to re-enum radios).

For a remote device you need just store its MAC. Then you can read any other information about remote device using this MAC.

Flominator

  • Guest
Thanks for the fast reply.

I made a mistake, rephrasing question, sorry:
OnDiscoveryComplete returns a wclBluetoothRadio with name "COMPUTERNAME". As learned some days ago, I store device and radio of the wclBluetoothDiscoveryCompleteEventArgs by creating a new wclBluetoothDevice and wclBluetoothRadio and perform assign() on the e objects. Then I store those two variables in a struct as a member variable on my tab pages. Some seconds later the radio is named "al Port".

Scenario is as follows: I have a separate bluetooth manager process which communicates with the main application via a named pipe. Once I successfully connected to the bluetooth device, I store address and radio. When the device stops responding and in some other cases, I terminate that manager process. On startup of the process afterwards I don't want to scan for all devices again, that's why I load stored local radio and remote MAC address to reconnect. It works like a charm, except this one case in Windows Xp when the device is in "standby" and the radio name changes after saving it. With this I don't find my old radio anymore and the user has to search again.

client.connect() reports "internal driver afterwards, but usually I don't even get that far, because EnumRadios() doesn't contains the initial radio name while my stored value is the new one.
« Last Edit: May 05, 2015, 04:58:27 PM by Flominator »

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
It looks like Radio object disposed. Can you show all the code? (you can send it to mike@btframework.com instead of posting here)

Flominator

  • Guest
Thanks for the hint, I will investigate. Am not sure if I can reduce the code to an amount that would be useful (and save ... bosses, you know ...?) to share.

Additional question: If it's disposed, shouldn't device name then be null?

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
No. It does not look completly disposed but partialy. What I mean is that memory has been corrupted by some reason. As you can see "al Port" probably is "Local Port" - a part of other string. As .NEt is managed it probably trys to dispose the object but not completly. See what I mean? Try to change your code to do not store Local Radio information but call EnumRadios instead. It is fast operation and easy. Simple call EnumRadios and get first found.

If EnumRadios fails then it is something with your thread/communication code which corrupts memory.

Flominator

  • Guest
Thanks for the suggestion, will try to use EnumRadios. The chance of somebody having multiple radios is close to zero, right?

Is the string "Local Port" used somewhere around WCL or is it just "a random string"?

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Thanks for the suggestion, will try to use EnumRadios. The chance of somebody having multiple radios is close to zero, right?

Yes, that's right.

Is the string "Local Port" used somewhere around WCL or is it just "a random string"?

Random. At least there is no such string in WCL.

Flominator

  • Guest
Using EnumRadios() works, but I would like to understand what happens anyway. What I figured out so far:

From OnDiscoveryComplete a method is called which adds device and radio to a struct:

Code: [Select]
      private void AddToListViewOnce(wcl.wclBluetoothDevice Device, ListViewItem item, wcl.wclBluetoothRadio radio)
      {
         TextLogger.LogInfo("A: Entering AddToListViewOnce:" + GetRadioName(radio));
         BTDevice btDevice = new BTDevice();
         btDevice.Device = new wclBluetoothDevice();
         btDevice.Device = Device;
         TextLogger.LogInfo("B: AddToListViewOnce:" + GetRadioName(radio));
         btDevice.Radio = new wclBluetoothRadio();
         btDevice.Radio = radio;

         item.Tag = btDevice;
         bool itemFound = false;
         foreach (ListViewItem oneItem in m_listViewDevices.Items)
         {
            if (((BTDevice)oneItem.Tag).Device.Address == Device.Address)
            {
               itemFound = true;
               TextLogger.LogInfo("TabPageDevices: device already in list, address: " + Device.Address);
               break;
            }
         }
         if (!itemFound)
         {
            m_listViewDevices.Items.Add(item);
         }
         TextLogger.LogInfo("Leaving AddToListViewOnce:" + GetRadioName(radio));
      }

   public string GetRadioName(wclBluetoothRadio radio)
      {
         string strName = "ZZundefinedZZ";
         int res = radio.GetName(ref strName);
         if (res != wclErrors.WCL_E_SUCCESS)
         {
            TextLogger.LogError("GetRadioName failed with " + wclErrors.wclGetErrorMessage(res));
         }
         return strName;
      }

Where the struct looks like this:
Code: [Select]
using System;
using wcl;

namespace ....

{
/// <summary>
/// save information of Bluetooth device
/// </summary>
internal struct BTDevice
{
      /// <summary>
      /// Device
      /// </summary>
public wclBluetoothDevice Device;
      /// <summary>
      /// Radio
      /// </summary>
      public wclBluetoothRadio Radio;
   }
}

When AddToListViewOnce is called for the second device found, the radio name gets "manipulated" between TextLogging points A and B. At logging point "A" it still is "COMPUTERNAME" and at logging point B it already is "al Port". Using .Assign() didn't help, neither did changing struct to class. Any clue?

Thanks in advance,

Flo
« Last Edit: May 06, 2015, 04:21:23 PM by Flominator »

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Hello,

The bug is in this code (I commented it a lttle bit)

private void AddToListViewOnce(wcl.wclBluetoothDevice Device, ListViewItem item, wcl.wclBluetoothRadio radio)
      {
         TextLogger.LogInfo("A: Entering AddToListViewOnce:" + GetRadioName(radio));
//!! You crearte new instance of wclBluetoothDevice object
         btDevice.Device = new wclBluetoothDevice();
//!! and simple assign one passes as parameter. Object you created has been lost (in non-managed languages you will get memeory leak here)
         btDevice.Device = Device; // Should be btDevice.Device.Assign(Device)
         TextLogger.LogInfo("B: AddToListViewOnce:" + GetRadioName(radio));
//!! same with radio
         btDevice.Radio = new wclBluetoothRadio();
         btDevice.Radio = radio; // Should be btDevice.Radio.Assign(radio)

Flominator

  • Guest
Had it like that before, tried again, didn't change a thing.

Remark/Correction: I have to admit that it happens on the first time the code is called, because the first device found doesn't lead to AddToListViewOnce being called.

Where I already perform .Assign() on both directly in OnDiscoveryComplete.
« Last Edit: May 06, 2015, 04:36:50 PM by Flominator »

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
That sounds strange because the only things I found I marked. If you told that it used Assign before (what is absolutely correct) so the problem somewere in other place.

Flominator

  • Guest
While the problem appears on WinXp 32bit baWidComm, but doesn't appear on Win7 64bit baMicrosoft . Does that ring any bell?

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Unfortunately no. Would be great to take a look on all your code to find where the problem can be. But since EnumRadios works it does not matter I think.

P.S.: It crashes on XP cause XP does not have good DEP protection.

Flominator

  • Guest
Just for documentation purposes: Problem persisted and was solved by workaround mentioned above.

 

Sitemap 1 2 3 4 5 6 7