Thread (6 messages) 6 messages, 2 authors, 2003-10-21

Re: [Bluez-devel] Re: command tx timeout and continuous inquiry.

From: Rene Mayrhofer <hidden>
Date: 2003-10-21 10:45:07

Hi Marcel,

Sorry to bother you again, but it still doesn't work as expected....

Marcel Holtmann wrote:
quoted
quoted
all CSR firmwares with HCI 16.x and greater are fine.
I will try a few devices at the hardware store to be sure to get a good 
firmware revision if I know what to look for. I'll look for CSR chipsets 
(easy to check), but which HCI Rev. and Subver. should I look for ? 
Which is the mimimum set of features that is needed ?

You can take a look at my web pages

	http://www.holtmann.org/linux/bluetooth/csr.html
I think I now have an adapter with correct firmware:

[rene@wall2 /tmp]$ sudo hciconfig -a
hci0:   Type: USB
         BD Address: 00:04:61:80:C3:DC ACL MTU: 192:8  SCO MTU: 64:8
         UP RUNNING PSCAN ISCAN
         RX bytes:99 acl:0 sco:0 events:13 errors:0
         TX bytes:296 acl:0 sco:0 commands:12 errors:0
         Features: 0xff 0xff 0x0b 0x00
         Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
         Link policy: HOLD SNIFF PARK
         Link mode: MASTER
         Name: 'Wally (0)'
         Class: 0x000100
         Service Classes: Unspecified
         Device Class: Computer, Uncategorized
         HCI Ver: 1.1 (0x1) HCI Rev: 0x20d LMP Ver: 1.1 (0x1) LMP 
Subver: 0x20d
         Manufacturer: Cambridge Silicon Radio (10)

[rene@wall2 /tmp]$ sudo hciconfig hci0 revision
hci0:   Type: USB
         BD Address: 00:04:61:80:C3:DC ACL MTU: 192:8  SCO MTU: 64:8
         HCI 16.4 (bc02x)

[rene@wall2 /tmp]$ cat /proc/version
Linux version 2.4.22 (root@wally) (gcc version 3.2.3 (Debian)) #1 Fri 
Sep 5 16:10:27 CEST 2003


However, I am still unable to create a second L2 connection (with BSD 
sockets) from two independent threads. A test run with my custom code 
shows the following (I've commented it a bit and the respective code is 
at the end of this mail):

Creating new L2Connection object for MAC 00:E0:00:C7:33:5E, starting 
ping thread now
<comment> This means that the MAC address 00:E0:00:C7:33:5E has been 
found during an inquiry (in a background inquiry thread) and that 
another thread was started specifically for this MAC. No connection has 
been made until now, only the inquiry. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 8
<comment> This means that the newly started thread has created a socket 
for Bluetooth and got socket descriptor 8 back from the socket call. 
</comment>

Creating new L2Connection object for MAC 00:02:C7:08:77:11, starting 
ping thread now
Creating new L2Connection object for MAC 00:01:E3:10:44:ED, starting 
ping thread now
<comment> Two more MAC addresses were found during the inquiry, so two 
additional threads are started. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:02:C7:08:77:11): 
opened socket 9
<comment> The socket was opened successfully. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run: Can't connect: Device 
or resource busy (16)
<comment> But the connect() call returned an error (16). </comment>

Deleting L2Connection object for MAC 00:02:C7:08:77:11, ping thread stopped
<comment> Since connect is not possible, the new thread immediately 
stops again. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:01:E3:10:44:ED): 
opened socket 9
BluetoothLinuxFeatureProvider::L2Connection::run: Can't connect: Device 
or resource busy (16)
Deleting L2Connection object for MAC 00:01:E3:10:44:ED, ping thread stopped
<comment> The same problem for the third MAC address. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
<comment> The first "ping" thread is running in the background and 
sending L2 echo packets. </comment>

Creating new L2Connection object for MAC 00:02:C7:08:77:11, starting 
ping thread now
BluetoothLinuxFeatureProvider::L2Connection::run (00:02:C7:08:77:11): 
opened socket 8
Creating new L2Connection object for MAC 00:01:E3:10:44:ED, starting 
ping thread now
BluetoothLinuxFeatureProvider::L2Connection::run: Can't connect: Device 
or resource busy (16)
Deleting L2Connection object for MAC 00:02:C7:08:77:11, ping thread stopped
BluetoothLinuxFeatureProvider::L2Connection::run (00:01:E3:10:44:ED): 
opened socket 8
BluetoothLinuxFeatureProvider::L2Connection::run: Can't connect: Device 
or resource busy (16)
Deleting L2Connection object for MAC 00:01:E3:10:44:ED, ping thread stopped
<comment> Another try at the two MAC addresses because they were again 
found in the inquiry. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
BluetoothLinuxFeatureProvider::L2Connection::run (00:E0:00:C7:33:5E): 
opened socket 6
<comment> This took nearly a minute (there is a 5 seconds delays between 
ping packets), during which no MAC addresses were found in the 
inquiries. Inquiries run constantly in the background with 3 seconds 
delay between inquiry attempts and about 6 seconds inquiry time. As soon 
as a stable "ping" connection is created, the inquiry call no longer 
returns any addresses. </comment>

no response from 00:E0:00:C7:33:5E: id 212
Deleting L2Connection object for MAC 00:E0:00:C7:33:5E, ping thread stopped
<comment> This was simply a timeout in this thread, although the devices 
were not moved. But in my experience, this just happens sometimes. 
</comment>

Creating new L2Connection object for MAC 00:01:E3:10:44:ED, starting 
ping thread now
Creating new L2Connection object for MAC 00:02:C7:08:77:11, starting 
ping thread now
<comment> As soon as the L2 connection is down, the inquiry works again 
and returns MAC addresses. </comment>

BluetoothLinuxFeatureProvider::L2Connection::run (00:01:E3:10:44:ED): 
opened socket 8
BluetoothLinuxFeatureProvider::L2Connection::run (00:02:C7:08:77:11): 
opened socket 9
BluetoothLinuxFeatureProvider::L2Connection::run: Can't connect: Device 
or resource busy (16)
Deleting L2Connection object for MAC 00:02:C7:08:77:11, ping thread stopped
<comment> Same story again. The first socket creation call succeeds, the 
second doesn't. </comment>

.....


This is the code responsible for the background inquiry thread:
void BluetoothLinuxFeatureProvider::run() throw()
{
	int dev_id = -1, length = 5, flags = 0 /*IREQ_CACHE_FLUSH*/,
		num_rsp;
	inquiry_info *info = NULL;
	bdaddr_t bdaddr;

	while (!this->isCancelled()) {
		/* hci_inquiry will malloc() the info structure for the found number
		   of devices */
		num_rsp = hci_inquiry(dev_id, length, 0, NULL, &info, flags);
		if (num_rsp >= 0) {
			for (int i = 0; i < num_rsp; i++) {
				char* macStr = NULL;
				baswap(&bdaddr, &(info+i)->bdaddr);
				macStr = batostr(&bdaddr);
				if (macStr != NULL) {
					// skipped a few checks here, this is only done if a thread is not 
already running for this MAC
					new L2Connection(this, macStr);
				}
			}
			if (info != NULL)
				free(info);
			// we have to set it to 0 so that hci_inquire will again malloc !
			info = NULL;
		}

		this->sleep(3000);
	}
}

And this is the "ping" code for the threads:

void BluetoothLinuxFeatureProvider::L2Connection::run() throw() {
	bool running = true, started = false;
	bdaddr_t bdaddr;
	int id;
	struct sockaddr_l2 addr;
	char buf[128];
	struct hci_conn_info_req *cr;
	struct hci_request rq;
	get_link_quality_rp rp;

	baswap(&bdaddr, strtoba(mac.c_str()));

	// intialize ping packet buffer
	for(unsigned int i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++)
		buf[i]=(i%40)+'A';

	memset(&addr, 0, sizeof(addr));
	addr.l2_family = AF_BLUETOOTH;

	id = ident;
	while (running) {
		struct timeval tv_send, tv_recv, tv_diff;
		l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf;
		int s, dd, dev_id;

		// first we need to create a Bluetooth socket
		if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) {
			plog("BluetoothLinuxFeatureProvider::L2Connection::run: Can't create 
socket: %s\n", strerror(errno));
			running = false;
			break;
		}
		plog("BluetoothLinuxFeatureProvider::L2Connection::run (%s): opened 
socket %d\n", mac.c_str(), s);

		bacpy(&(addr.l2_bdaddr), BDADDR_ANY);
         	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
			plog("BluetoothLinuxFeatureProvider::L2Connection::run: Can't bind 
socket.\n");
			running = false;
			close(s);
			break;
         	}

		// connect to the remote host
		bacpy(&addr.l2_bdaddr, &bdaddr);
// here the problem starts
		if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
			plog("BluetoothLinuxFeatureProvider::L2Connection::run: Can't 
connect: %s (%d)\n", strerror(errno), errno);
			running = false;
			close(s);
			break;
		}

		/* Build command header */
<snip>

	plog("Deleting L2Connection object for MAC %s, ping thread stopped\n", 
mac.c_str());

}

Most of the code has been taken from hcitool and simply has been adapted 
to the framework. What is not shown here (the <skip> block) is that, 
after a successfully received reply packet, I also open a HCI socket 
with hci_open_dev to get the L2 link quality (code taken from hcitool 
con). Both sockets are closed immediately afterwards in the ping loop. 
Then there is a delay of 5 seconds and it starts again to open the L2 
socket.

Do you have any other pointers on what might go wrong here ? I am 
grateful for any hint. We don't have very much money to spend on 
hardware here at the university, but another Bluetooth adapter should be 
doable :)

best regards,
Rene
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help