linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Bluez-devel] Strange behaviour
@ 2006-05-17 17:51 Brand, Chris
  2006-05-29 13:22 ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-17 17:51 UTC (permalink / raw)
  To: bluez-devel

This is some test code that uses rfcomm to send data back and forth
between two hosts.
It seems to behave as expected to start with, but after a while data
stops flowing in one direction, and in the other direction it gets very
bursty.

This is on Fedora Core 4 (2.6.14 kernel) on one machine and FC3 (2.6.12)
on the other, with two identical CSR bluetooth modules :=20
hci0:	Type: USB
	BD Address: 00:02:5B:01:BE:72 ACL MTU: 384:8  SCO MTU: 64:8
	UP RUNNING PSCAN ISCAN=20
	RX bytes:18388796 acl:55829 sco:0 events:29399 errors:0
	TX bytes:14666019 acl:53268 sco:0 commands:24 errors:0
	Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80
	Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3=20
	Link policy: RSWITCH HOLD SNIFF PARK=20
	Link mode: SLAVE ACCEPT=20
	Name: 'Spring'
	Class: 0x120104
	Service Classes: Networking, Object Transfer
	Device Class: Computer, Desktop workstation
	HCI Ver: n/a (0x3) HCI Rev: 0x77b LMP Ver: n/a (0x3) LMP Subver:
0x77b
	Manufacturer: Cambridge Silicon Radio (10)

Is this something wrong in my test code ? Is it a bug in the bluez stack
? Is it specific to this hardware ?

Any help would be much appreciated. Thanks.

Here's the code :

#include <arpa/inet.h>
#include <bits/sockaddr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <linux/types.h>
#include <linux/irda.h>




#define ASSERT( aCondition, aResult, aMessage )		if
(!(aCondition)) {fprintf (stderr, "%s [%d]: %s (%d)\n", __FUNCTION__,
__LINE__, (aMessage), (aResult)); return (aResult);}
#define CHECK_RESULT( aResult, aMessage )			ASSERT
((aResult) =3D=3D 0, (aResult), (aMessage))
#define CHECK_BLOCK( aBlock, aResult, aMessage )	ASSERT ((aBlock)
!=3D NULL, (aResult), (aMessage))
#define DEBUG_LOG_STATUS(...)
fprintf (stderr, "[Status] "); fprintf (stderr, __VA_ARGS__); fprintf
(stderr, "\n")
//#define DEBUG_LOG_TRACE(...)
fprintf (stderr, "[Trace] %s:", __FUNCTION__); fprintf (stderr,
__VA_ARGS__); fprintf (stderr, "\n")
#define DEBUG_LOG_TRACE
#ifndef FALSE
#	define FALSE	(0)
#endif
#ifndef TRUE
#	define TRUE		(!(FALSE))
#endif
#define MEMBER_SIZEOF( aType, aMember )		sizeof ((const aType
*)(0)->aMember)


enum
{
	_kFCSSeed =3D 0xFFFF
};

enum
{
	_kOptRFCOMMChannel	=3D 'c',
	_kOptEcho			=3D 'e',
	_kOptHeaderSize		=3D 'H',
	_kOptMinPayload		=3D 'm',
	_kOptMaxPayload		=3D 'M',
	_kOptPayloadSize	=3D 'p',
	_kOptReverseRole	=3D 'r',
=09
	_kOptTakesArgument	=3D ':'
};

enum
{
	_kPrimaryModuleFlags =3D (1UL << HCI_UP) | (1UL << HCI_PSCAN) |
(1UL << HCI_ISCAN)
};

enum
{
	_kDefaultMTU =3D 256
};



typedef struct _COptions
{
	const char *	mServiceName;
	uint8_t			mChannel;
	int				mIsClient;
	int				mIsInitiator;
	ssize_t			mMinPayload;
	ssize_t			mMaxPayload;
	ssize_t			mHeaderSize;
	int				mEcho;
} _COptions;


typedef struct _CDiscoveryLog
{
	struct irda_device_list		mHeader;
	struct irda_device_info		mSlots01to0F [15];
} _CDiscoveryLog;


typedef struct _CTestPacketHeader
{
	uint16_t	mFCS;
	uint16_t	mSize;
	bdaddr_t	mSource;
	uint32_t	mSent;
	uint32_t	mReceived;
} _CTestPacketHeader __attribute__ ((packed));


typedef struct _CTestPacket
{
	_CTestPacketHeader	mHeader;
	uint8_t				mPayload [65532 - sizeof
(_CTestPacketHeader)];
} _CTestPacket __attribute__ ((packed));



static int					sReceiveCount;
static int					sQuit =3D FALSE;
static struct sigaction		sOnSIGINT;
static const uint16_t
fcstbl [256] =3D {
	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};



static
void
_timeval_sub (
	const struct timeval *	inLHS,
	const struct timeval *	inRHS,
	struct timeval *		outResult)
{
	struct timeval	rhs =3D *inRHS;
=09
=09
	if (inLHS =3D=3D NULL  ||  inRHS =3D=3D NULL  ||  outResult =3D=3D =
NULL)
	{
		return;
	}
=09
	*outResult =3D *inLHS;
	rhs =3D *inRHS;
=09
	while (rhs.tv_usec >=3D 1000000)
	{
		rhs.tv_sec++;
		rhs.tv_usec -=3D 1000000;
	}
=09
	if (outResult->tv_usec >=3D rhs.tv_usec)
	{
		outResult->tv_usec -=3D rhs.tv_usec;
		outResult->tv_sec -=3D rhs.tv_sec;
	}
=09
	else
	{
		outResult->tv_usec =3D outResult->tv_usec + 1000000 -
rhs.tv_usec;
		outResult->tv_sec =3D outResult->tv_sec - 1 - rhs.tv_sec;
	}
=09
	while (outResult->tv_usec >=3D 1000000)
	{
		outResult->tv_sec++;
		outResult->tv_usec -=3D 1000000;
	}
}



static
int
_CheckPacket (
	const _CTestPacket *	inPacket)
{
	int			size;
	uint16_t	fcs =3D _kFCSSeed;
	uint8_t *	packet =3D (uint8_t *) &inPacket->mHeader.mSize;
	uint8_t		byte;
=09
=09
	CHECK_BLOCK (inPacket, FALSE, "null _CTestPacket");
=09
	for (
		size =3D ntohs (inPacket->mHeader.mSize) - sizeof
(inPacket->mHeader.mFCS);
		size > 0; --size)
	{
		byte =3D *packet++;
		fcs =3D (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
=09
	return (fcs =3D=3D ntohs (inPacket->mHeader.mFCS));
}



static
size_t
_MakeTestPacket (
	bdaddr_t	inSource,
	uint32_t	inSent,
	uint32_t	inReceived,
	ssize_t		inMinPayload,
	ssize_t		inMaxPayload,
	_CTestPacket *	outPacket)
{
	ssize_t		range;
	ssize_t		size =3D inMinPayload;
	uint16_t	fcs =3D _kFCSSeed;
	int			offset;
	uint8_t *	packet =3D (uint8_t *) &outPacket->mHeader.mSize;
	uint8_t		byte;
=09
=09
	CHECK_BLOCK (outPacket, 0, "null _CTestPacket");
=09
	if (size < 0)
	{
		size =3D 0;
	}
=09
	else if (size > sizeof (outPacket->mPayload))
	{
		size =3D sizeof (outPacket->mPayload);
	}
=09
	if (size > inMaxPayload)
	{
		size =3D inMaxPayload;
	}
=09
	range =3D inMaxPayload - size;
=09
	if (range > sizeof (outPacket->mPayload) - size)
	{
		range =3D sizeof (outPacket->mPayload) - size;
	}
	DEBUG_LOG_TRACE ("min =3D %ld  range =3D %ld", size, range);=09
=09
	if (range > 0)
	{
		size +=3D rand () % (range + 1);
	}
=09
	outPacket->mHeader.mSize =3D htons (size + sizeof
(outPacket->mHeader));
	outPacket->mHeader.mSource =3D inSource;
	outPacket->mHeader.mSent =3D htonl (inSent);
	outPacket->mHeader.mReceived =3D htonl (inReceived);
=09
	for (
		offset =3D sizeof (outPacket->mHeader.mFCS);
		offset < sizeof (outPacket->mHeader);
		offset++)
	{
		byte =3D *packet++;
		fcs =3D (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
=09
	while (size > 0)
	{
		--size;
		byte =3D rand ();
		*packet++ =3D byte;
		fcs =3D (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
=09
	outPacket->mHeader.mFCS =3D htons (fcs);
=09
	ASSERT (_CheckPacket (outPacket), 0, "_MakeTestPacket () failed
_CheckPacket ()");
=09
	return ntohs (outPacket->mHeader.mSize);
}



static
int
_GetPacket (
	int				inSocket,
	_CTestPacket *	outPacket)
{
	int			result =3D 0;
	uint8_t *	packet =3D (uint8_t *) outPacket;
	size_t		expected =3D sizeof (outPacket->mHeader);
	size_t		allowed =3D sizeof (*outPacket);
	size_t		received =3D 0;
	int			size;
	int			check;
	uint8_t		overflow [256];
=09
=09
	CHECK_BLOCK (outPacket, EINVAL, "null _CTestPacket");
=09
=09
	// Get packet header:
=09
	do
	{
		size =3D read (inSocket, packet, expected - received);
	=09
		if (size > 0)
		{
			DEBUG_LOG_TRACE ("expected =3D %lu, received =3D
%lu", expected, received);
			received +=3D size;
			packet +=3D size;
		}
	}
	while (size > 0  &&  received < expected);
=09
	result =3D errno;
=09
	if (size < 0)
	{
		if (sQuit  ||  result =3D=3D ECONNRESET)
		{
			return result;
		}
	=09
		CHECK_RESULT (result, "read () failed");
		CHECK_RESULT (-1, "read () failed");
	}
=09
	ASSERT (!(received < expected), EIO, "received less than
expected");
=09
=09
	// Get payload:
=09
	expected =3D ntohs (outPacket->mHeader.mSize);
	DEBUG_LOG_STATUS ("Rx:
exp: %6lu", expected);
=09
	if (expected < sizeof (*outPacket))
	{
		allowed =3D expected;
	}
=09
	else
	{
		allowed =3D sizeof (*outPacket);
	}
=09
	while (size > 0  &&  received < allowed)
	{
		DEBUG_LOG_TRACE ("allowed =3D %lu, received =3D %lu",
allowed, received);
		size =3D read (inSocket, packet, allowed - received);
	=09
		if (size > 0)
		{
			received +=3D size;
			packet +=3D size;
		}
	}
=09
	while (size > 0  &&  received < expected)
	{
		DEBUG_LOG_TRACE ("expected =3D %lu, received =3D %lu",
expected, received);
		size =3D read (inSocket, overflow, sizeof (overflow));
	=09
		if (size > 0)
		{
			received +=3D size;
			packet +=3D size;
		}
	}
=09
	DEBUG_LOG_TRACE ("expected =3D %lu, received =3D %lu", expected,
received);
	result =3D errno;
=09
	if (size < 0)
	{
		if (sQuit  ||  result =3D=3D ECONNRESET)
		{
			return result;
		}
	=09
		CHECK_RESULT (result, "read () failed");
		CHECK_RESULT (-1, "read () failed");
	}
=09
	ASSERT (!(received < expected), EIO, "received less than
expected");
	ASSERT (!(received > expected), EIO, "received more than
expected");
=09
	if (size =3D=3D 0)
	{
		return ECONNRESET;
	}
=09
	return 0;
}



static
int
_Send (
	int				inSocket,
	const void *	inPacket,
	size_t			inSize,
	ssize_t			inHeaderSize)
{
	int					result =3D 0;
	const uint8_t *		packet =3D (const uint8_t *) inPacket;
	size_t				remaining;
	int					size =3D 0;
=09
=09
	ASSERT (inSize =3D=3D 0  ||  packet !=3D NULL, EINVAL, "null packet");
=09
	if (inSize >=3D inHeaderSize  &&  inHeaderSize > 0)
	{
		size =3D write (inSocket, packet, inHeaderSize);
	=09
		if (size > 0)
		{
			inSize -=3D size;
			packet +=3D size;
		}
	=09
		else
		{
			inSize =3D size;
		}
	}
=09
	while (inSize > 0)
	{
		size =3D write (inSocket, packet, inSize);
	=09
		if (size > 0)
		{
			inSize -=3D size;
			packet +=3D size;
		}
	=09
		else
		{
			inSize =3D size;
		}
	}
=09
	result =3D errno;
=09
	if (size < 0)
	{
		if (sQuit  ||  result =3D=3D ECONNRESET)
		{
			return result;
		}
	=09
		CHECK_RESULT (result, "write () failed");
		CHECK_RESULT (-1, "write () failed");
	}
=09
	return 0;
}



static
void *
_ReadThread (
	void *	arg)
{
	static _CTestPacket		sIn;
	int						sd =3D *(int *)
arg;
	int						error =3D 0;
	struct timeval			start;
	struct timeval			end;
	time_t					usec =3D 0;
	ssize_t					rate;
	int						size;
	int						ok;
	const char *			check =3D "";
	char					sourceName [32];
=09
=09
	while (!sQuit)
	{
		rate =3D 0;
		gettimeofday (&start, NULL);
	=09
		error =3D _GetPacket (sd, &sIn);
		gettimeofday (&end, NULL);
	=09
		if (sQuit  ||  error =3D=3D ECONNRESET)
		{
			return 0;
		}
	=09
		ASSERT ((error =3D=3D 0), NULL, "_GetPacket () failed");
	=09
		ok =3D _CheckPacket (&sIn);
	=09
		if (ok)
		{
			sReceiveCount++;
			check =3D "";
		}
	=09
		else
		{
			check =3D "  fcs [FAILED]";
		}
	=09
		DEBUG_LOG_TRACE ("start: sec =3D %ld  usec =3D %ld",
start.tv_sec, start.tv_usec);
		DEBUG_LOG_TRACE ("end: sec =3D %ld  usec =3D %ld",
end.tv_sec, end.tv_usec);
		_timeval_sub (&end, &start, &end);
		DEBUG_LOG_TRACE ("dur: sec =3D %ld  usec =3D %ld",
end.tv_sec, end.tv_usec);
		usec =3D (end.tv_sec * 1000000) + end.tv_usec;
	=09
		if (usec <=3D 0)
		{
			usec =3D 1;
		}
	=09
		ba2str (&sIn.mHeader.mSource, sourceName);
		size =3D ntohs (sIn.mHeader.mSize);
	=09
		DEBUG_LOG_STATUS (
			"Rx: src: %s  sent: %5lu  rcvd: %5lu  size:
%6d%s",
			sourceName,
			ntohl (sIn.mHeader.mSent),
			ntohl (sIn.mHeader.mReceived),
			size,
			check);
	=09
/*		size +=3D rate;
		rate =3D (((long long) size) * 8 * 1000000) / usec;
	=09
		DEBUG_LOG_STATUS (
			"RT:
size: %6d   ms: %5ld  bps: %6ld",
			size,
			((usec + 500) / 1000),
			rate);
*/	=09
		sched_yield ();
	}
}



static
int
_LoopTest (
	int					inSocket,
	const _COptions *	inOptions)
{
	static _CTestPacket		sOut;
	pthread_t				rx;
	uint32_t				sent =3D 0;
	socklen_t				optsize;
	int						error =3D 0;
	int						mtu =3D 0;
	ssize_t					min;
	ssize_t					max;
	struct sockaddr_rc		me;
	struct timeval			start;
	struct timeval			end;
	time_t					usec =3D 0;
	ssize_t					rate;
	int						size;
	char					sourceName [32];
=09
=09
/*	optsize =3D sizeof (mtu);
	error =3D getsockopt (inSocket, SOL_IRLMP, IRTTP_MAX_SDU_SIZE,
&mtu, &optsize);
=09
	if (error =3D=3D 0  &&  mtu > 0)
	{
		DEBUG_LOG_STATUS ("MTU =3D %d", mtu);
	}
=09
	else
	{
		mtu =3D 0;
	}
*/=09
	sReceiveCount =3D 0;
=09
	error =3D pthread_create (&rx, NULL, _ReadThread, &inSocket);
	CHECK_RESULT (error, "pthread_create () failed");
=09
	min =3D inOptions->mMinPayload;
	max =3D inOptions->mMaxPayload;
=09
	if (max < 0)
	{
		if (min > mtu)
		{
			max =3D min;
		}
	=09
		else
		{
			if (mtu <=3D 0)
			{
				mtu =3D _kDefaultMTU;
				DEBUG_LOG_STATUS ("MTU unknown. Assuming
%d", mtu);
			}
		=09
			max =3D mtu - sizeof (_CTestPacketHeader);
		}
	}
=09
	optsize =3D sizeof (me);
	getsockname (inSocket, (struct sockaddr *) &me, &optsize);
=09
=09
	while (!sQuit)
	{
		size =3D _MakeTestPacket (me.rc_bdaddr, sent,
sReceiveCount, min, max, &sOut);
		gettimeofday (&start, NULL);
		error =3D _Send (inSocket, &sOut, size,
inOptions->mHeaderSize);
	=09
		if (sQuit  ||  error =3D=3D ECONNRESET)
		{
			return 0;
		}
	=09
		CHECK_RESULT (error, "_Send () failed");
	=09
		sent++;
	=09
		ba2str (&sOut.mHeader.mSource, sourceName);
	=09
		DEBUG_LOG_STATUS (
			"Tx: src: %s  sent: %5lu  rcvd: %5lu  size:
%6d",
			sourceName,
			ntohl (sOut.mHeader.mSent),
			ntohl (sOut.mHeader.mReceived),
			ntohs (sOut.mHeader.mSize));
	=09
		sched_yield ();
	}
=09
	return 0;
}



static
int
_RfConnect (
	bdaddr_t			inPeer,
	const _COptions *	inOptions)
{
	int					error;
	int					sd =3D -1;
	struct sockaddr_rc	peer;
	char				peerName [32];
	int					size;
	char				buffer [2048];
=09
=09
	CHECK_BLOCK (inOptions, EINVAL, "null _COptions");

	memset (&peer, 0, sizeof (peer));
	peer.rc_family =3D AF_BLUETOOTH;
	peer.rc_bdaddr =3D inPeer;
	peer.rc_channel =3D inOptions->mChannel;
=09
	sd =3D socket (PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
=09
	if (sd =3D=3D -1)
	{
		CHECK_RESULT (errno, "socket () failed");
		CHECK_RESULT (-1, "socket () failed");
	}
=09
	ba2str (&peer.rc_bdaddr, peerName);
=09
	DEBUG_LOG_STATUS ("Connecting to [%s] CH [%d]...", peerName,
((int) peer.rc_channel));
	error =3D connect (sd, (const struct sockaddr *) (&peer), sizeof
(peer));
=09
	if (error !=3D 0)
	{
		close (sd);
		CHECK_RESULT (errno, "connect () failed");
		CHECK_RESULT (-1, "connect () failed");
	}
=09
	DEBUG_LOG_STATUS ("Connected");
=09
	error =3D _LoopTest (sd, inOptions);
=09
	if (error !=3D 0)
	{
		close (sd);
		CHECK_RESULT (error, "_LoopTest () failed");
	}
=09
	DEBUG_LOG_STATUS ("Disconnected");
	close (sd);
=09
	return 0;
}



static
int
_OnIsPrimaryModule (
	int		inSocket,
	int		inDeviceID,
	long	inContext)
{
=09
	struct hci_dev_info		info;
=09
=09
	(void) inContext;
=09
	DEBUG_LOG_TRACE ("_OnIsPrimaryModule (%d)", inDeviceID);
	if (hci_devinfo (inDeviceID, &info) !=3D 0)
	{
		return FALSE;
	}
=09
	DEBUG_LOG_TRACE ("_OnIsPrimaryModule: %s", info.name);
	return ((info.flags & _kPrimaryModuleFlags) =3D=3D
_kPrimaryModuleFlags);
}



static
int
_RfGetPrimaryBDA (
	bdaddr_t *	outBDA)
{
	int		hci =3D -1;
=09
=09
	CHECK_BLOCK (outBDA, EINVAL, "null bdaddr_t");
=09
	hci =3D hci_for_each_dev (HCI_UP, _OnIsPrimaryModule, 0L);
	ASSERT ((hci >=3D 0), ENODEV, "No bluetooth modules");
=09
	ASSERT ((hci_devba (hci, outBDA) =3D=3D 0), errno, "hci_devba ()
failed");
	return 0;
}



static
int
_RfListen (
	const _COptions *	inOptions)
{
	int					error;
	int					listener =3D -1;
	struct sockaddr_rc	local;
	bdaddr_t			primary;
	char				localName [32];
	struct sockaddr_rc	peer;
	char				peerName [32];
	int					connection;
	socklen_t			size =3D 0;
=09
=09
	CHECK_BLOCK (inOptions, EINVAL, "null _COptions");
=09
	memset (&local, 0, sizeof (local));
	local.rc_family =3D AF_BLUETOOTH;
	local.rc_bdaddr =3D *BDADDR_ANY;
	local.rc_channel =3D inOptions->mChannel;
=09
	listener =3D socket (PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
=09
	if (listener =3D=3D -1)
	{
		CHECK_RESULT (errno, "socket () failed");
		CHECK_RESULT (-1, "socket () failed");
	}
=09
	error =3D bind (listener, (const struct sockaddr *) &local, sizeof
(local));
=09
	if (error !=3D 0)
	{
		close (listener);
		CHECK_RESULT (errno, "connect () failed");
		CHECK_RESULT (-1, "connect () failed");
	}
=09
	error =3D listen (listener, 1);
=09
	if (error !=3D 0)
	{
		close (listener);
		CHECK_RESULT (errno, "listen () failed");
		CHECK_RESULT (-1, "listen () failed");
	}
=09
	size =3D sizeof (local);
	getsockname (listener, (struct sockaddr *) &local, &size);
	CHECK_RESULT (_RfGetPrimaryBDA (&primary), "_RfGetPrimaryBDA ()
failed");
	ba2str (&primary, localName);
	DEBUG_LOG_STATUS (
		"Waiting for connection to [%s] CH [%d]...", localName,
		((int) local.rc_channel));
=09
	size =3D sizeof (peer);
	connection =3D accept (listener, (struct sockaddr *) &peer,
&size);
	error =3D errno;
	close (listener);
=09
	if (connection =3D=3D -1)
	{
		if (sQuit)
		{
			return 0;
		}
	=09
		CHECK_RESULT (error, "accept () failed");
		CHECK_RESULT (-1, "accept () failed");
	}
=09
	DEBUG_LOG_STATUS ("Connected");
=09
	error =3D _LoopTest (connection, inOptions);
=09
	if (error !=3D 0)
	{
		close (connection);
		CHECK_RESULT (error, "_LoopTest () failed");
	}
=09
	DEBUG_LOG_STATUS ("Disconnected");
	close (connection);
=09
	return 0;
}



static
uint32_t
_GetPeer (
	void)
{
	int				sd =3D -1;
	_CDiscoveryLog	log;
	socklen_t		size =3D sizeof (log);
	int				index;
=09
=09
	sd =3D socket (AF_IRDA, SOCK_SEQPACKET, 0);
	ASSERT (sd !=3D -1, 0, "socket () failed");
=09
	memset (&log, 0, sizeof (log));
=09
	if (getsockopt (sd, SOL_IRLMP, IRLMP_ENUMDEVICES, &log, &size)
!=3D 0)
	{
		ASSERT (FALSE, 0, "getsockopt (IRLMP_ENUMDEVICES)
failed");
	}
=09
	close (sd);
=09
	for (index =3D 0; index < log.mHeader.len; index++)
	{
		if (log.mHeader.dev [index].daddr !=3D 0)
		{
			DEBUG_LOG_STATUS ("Found \"%s\"",
log.mHeader.dev [index].info);
			return log.mHeader.dev [index].daddr;
		}
	}
=09
	DEBUG_LOG_STATUS ("no devices");
	return 0;
}



static
void
_OnSIGINT (
	int				signo,
	siginfo_t *		info,
	void *			context)
{
	if (sQuit > 1)
	{
		sigaction (SIGINT, &sOnSIGINT, NULL);
	}
=09
	sQuit++;
}



static
void
_PrintUsage (
	const char	inName [])
{
	const char *	parse;
=09
=09
	for (parse =3D inName; *parse !=3D '\0'; parse++)
	{
		if (*parse =3D=3D '/')
		{
			parse++;
		=09
			if (*parse =3D=3D '\0')
			{
				break;
			}
		=09
			inName =3D parse;
		}
	}
=09
	fprintf (
		stderr,
		"Usage: %s -c <channel> [OPTION]... [TARGET_BDA]\n"
		"Send and receive RFCOMM messages in the following
format.  Offsets and sizes\n"
		"are in octets, and field values are in network byte
order.\n"
		"\n"
		"OFFSET       SIZE   FIELD\n"
		"     0          2   FCS        RFC 1171 CRC from next
field to end of message\n"
		"     2          2   Size       Size of message from
offset 0 to end of message\n"
		"     4          6   Source     IrLAP address of message
originator\n"
		"    10          4   Sent       Number of messages
origniator sent before this\n"
		"    14          4   Received   Number of valid messages
originator has received\n"
		"    18  Size - 18   Payload    Random data.  The
payload size varies randomly\n"
		"                               within the range
determined by -m, -M, and -p\n"
		"                               options or their
defaults.\n"
		"\n"
		"\n"
		"A -c option is required.\n"
		"\n"
		"Protocol Options:\n"
		"  -c <channel>   client mode, where <channel> is the
RFCOMM channel to\n"
		"                 which to connect.  Overrides any
previous -c options.\n"
		"\n"
		"Data Options:\n"
		"  -m <size>      minimum payload size.  Overrides any
previous -m or -p\n"
		"                 options. [Default: 0]\n"
		"  -M <size>      maximum payload size.  Overrides any
previous -M or -p\n"
		"                 options. [Default: fit to MTU]\n"
		"  -p <size>      exact payload size.  Overrides any
previous -m or -M\n"
		"                 options. [Default: see -m and -M]\n"
		"  -H <size>      send each message as a header of
<size> bytes followed by\n"
		"                 the rest of the message [Default:
0]\n"
		, inName
	);
}



int
main (
	int				argc,
	char * const	argv [])
{
	static const char	sOptionList [] =3D {
=09
_kOptRFCOMMChannel, _kOptTakesArgument,
//							_kOptEcho,
							_kOptHeaderSize,
_kOptTakesArgument,
							_kOptMinPayload,
_kOptTakesArgument,
							_kOptMaxPayload,
_kOptTakesArgument,
=09
_kOptPayloadSize, _kOptTakesArgument,
							_kOptReverseRole
						};
	struct sigaction	action;
	unsigned			seed =3D time (NULL);
	_COptions			options;
	int					opt;
	const char *		arg =3D NULL;
	int					reverse =3D FALSE;
	int					error;
	bdaddr_t			rfPeer;
=09
=09
	action.sa_handler =3D NULL;
	action.sa_flags =3D SA_SIGINFO;
	action.sa_sigaction =3D _OnSIGINT;
	sigemptyset (&action.sa_mask);
=09
//	sigaction (SIGINT, &action, &sOnSIGINT);
=09
	memset (&options, 0, sizeof (options));
	options.mMaxPayload =3D -1; // mtu
=09
	do
	{
		opt =3D getopt (argc, argv, sOptionList);
	=09
		if (optarg !=3D NULL  &&  optarg [0] =3D=3D '=3D')
		{
			arg =3D optarg + 1;
		}
	=09
		else
		{
			arg =3D optarg;
		}
	=09
		switch (opt)
		{
			case _kOptMaxPayload:
			{
				options.mMaxPayload =3D strtoul (arg,
NULL, 0);
			}
			break;
		=09
		=09
			case _kOptEcho:
			{
				options.mEcho =3D TRUE;
			}
			break;
		=09
		=09
			case _kOptHeaderSize:
			{
				options.mHeaderSize =3D strtoul (arg,
NULL, 0);
			}
			break;
		=09
		=09
			case _kOptReverseRole:
			{
				reverse =3D !reverse;
			}
			break;
		=09
		=09
			case _kOptMinPayload:
			{
				options.mMinPayload =3D strtoul (arg,
NULL, 0);
			}
			break;
		=09
		=09
			case _kOptPayloadSize:
			{
				options.mMinPayload =3D strtoul (arg,
NULL, 0);
			}
			break;
		=09
		=09
			case _kOptRFCOMMChannel:
			{
				options.mChannel =3D strtoul (arg, NULL,
0);
			}
			break;
		}
	}
	while (opt !=3D -1);
=09
=09
	if (options.mChannel =3D=3D 0)
	{
		_PrintUsage (argv [0]);
		return 1;
	}
=09
	if (optind < argc)
	{
		if (str2ba (argv [argc - 1], &rfPeer) !=3D 0)
		{
			_PrintUsage (argv [0]);
			return 1;
		}
	=09
		options.mIsClient =3D TRUE;
	}
=09
	if (reverse)
	{
		options.mIsInitiator =3D !options.mIsClient;
	}
=09
	else
	{
		options.mIsInitiator =3D options.mIsClient;
	}
=09
	srand (seed);
	DEBUG_LOG_STATUS ("Random seed =3D %u", seed);
=09
=09
	while (!sQuit)
	{
		if (options.mIsClient)
		{
			_RfConnect (rfPeer, &options);
		=09
			sleep (3);
		}
	=09
		else
		{
			error =3D _RfListen (&options);
			CHECK_RESULT (error, "_RfListen () failed");
		}
	}
=09
	return 0;
}
=20
Chris Brand
Senior Software Engineer
WideRay
604-233-1105
=20


-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-17 17:51 Brand, Chris
@ 2006-05-29 13:22 ` Marcel Holtmann
  2006-05-29 16:13   ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 13:22 UTC (permalink / raw)
  To: bluez-devel

Hi Chris,

> This is some test code that uses rfcomm to send data back and forth
> between two hosts.
> It seems to behave as expected to start with, but after a while data
> stops flowing in one direction, and in the other direction it gets very
> bursty.

please send the code as attachment. It seems your mailer messed up the
whitespaces.

> Is this something wrong in my test code ? Is it a bug in the bluez stack
> ? Is it specific to this hardware ?

Could be one of it or even both. How do I run the test case and what
should I look for?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 13:22 ` Marcel Holtmann
@ 2006-05-29 16:13   ` Brand, Chris
  2006-05-29 17:36     ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 16:13 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 650 bytes --]

Hi Marcel,

> please send the code as attachment. It seems your mailer 
> messed up the whitespaces.

Attached. Sorry about that.

> How do I run the test case 
> and what should I look for?

On one node, I run it with "./rfcommloop -c 1 -M 1024". It reports the
bluetooth address of the device it's using. On the other node, use the
same command line but append the reported bluetooth address.

It will report number of packets sent and received at each end. After a
while (seems to be fairly random, as far as I can tell), the numbers for
packets flowing in one direction (again, which way seems random) stop
increasing.

Chris

[-- Attachment #2: rfcommloop.c --]
[-- Type: application/octet-stream, Size: 22356 bytes --]

#include <arpa/inet.h>
#include <bits/sockaddr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <linux/types.h>
#include <linux/irda.h>




#define ASSERT( aCondition, aResult, aMessage )		if (!(aCondition)) {fprintf (stderr, "%s [%d]: %s (%d)\n", __FUNCTION__, __LINE__, (aMessage), (aResult)); return (aResult);}
#define CHECK_RESULT( aResult, aMessage )			ASSERT ((aResult) == 0, (aResult), (aMessage))
#define CHECK_BLOCK( aBlock, aResult, aMessage )	ASSERT ((aBlock) != NULL, (aResult), (aMessage))
#define DEBUG_LOG_STATUS(...)						fprintf (stderr, "[Status] "); fprintf (stderr, __VA_ARGS__); fprintf (stderr, "\n")
//#define DEBUG_LOG_TRACE(...)						fprintf (stderr, "[Trace] %s:", __FUNCTION__); fprintf (stderr, __VA_ARGS__); fprintf (stderr, "\n")
#define DEBUG_LOG_TRACE
#ifndef FALSE
#	define FALSE	(0)
#endif
#ifndef TRUE
#	define TRUE		(!(FALSE))
#endif
#define MEMBER_SIZEOF( aType, aMember )		sizeof ((const aType *)(0)->aMember)


enum
{
	_kFCSSeed = 0xFFFF
};

enum
{
	_kOptRFCOMMChannel	= 'c',
	_kOptEcho			= 'e',
	_kOptHeaderSize		= 'H',
	_kOptMinPayload		= 'm',
	_kOptMaxPayload		= 'M',
	_kOptPayloadSize	= 'p',
	_kOptReverseRole	= 'r',
	
	_kOptTakesArgument	= ':'
};

enum
{
	_kPrimaryModuleFlags = (1UL << HCI_UP) | (1UL << HCI_PSCAN) | (1UL << HCI_ISCAN)
};

enum
{
	_kDefaultMTU = 256
};



typedef struct _COptions
{
	const char *	mServiceName;
	uint8_t			mChannel;
	int				mIsClient;
	int				mIsInitiator;
	ssize_t			mMinPayload;
	ssize_t			mMaxPayload;
	ssize_t			mHeaderSize;
	int				mEcho;
} _COptions;


typedef struct _CDiscoveryLog
{
	struct irda_device_list		mHeader;
	struct irda_device_info		mSlots01to0F [15];
} _CDiscoveryLog;


typedef struct _CTestPacketHeader
{
	uint16_t	mFCS;
	uint16_t	mSize;
	bdaddr_t	mSource;
	uint32_t	mSent;
	uint32_t	mReceived;
} _CTestPacketHeader __attribute__ ((packed));


typedef struct _CTestPacket
{
	_CTestPacketHeader	mHeader;
	uint8_t				mPayload [65532 - sizeof (_CTestPacketHeader)];
} _CTestPacket __attribute__ ((packed));



static int					sReceiveCount;
static int					sQuit = FALSE;
static struct sigaction		sOnSIGINT;
static const uint16_t
fcstbl [256] = {
	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};



static
void
_timeval_sub (
	const struct timeval *	inLHS,
	const struct timeval *	inRHS,
	struct timeval *		outResult)
{
	struct timeval	rhs = *inRHS;
	
	
	if (inLHS == NULL  ||  inRHS == NULL  ||  outResult == NULL)
	{
		return;
	}
	
	*outResult = *inLHS;
	rhs = *inRHS;
	
	while (rhs.tv_usec >= 1000000)
	{
		rhs.tv_sec++;
		rhs.tv_usec -= 1000000;
	}
	
	if (outResult->tv_usec >= rhs.tv_usec)
	{
		outResult->tv_usec -= rhs.tv_usec;
		outResult->tv_sec -= rhs.tv_sec;
	}
	
	else
	{
		outResult->tv_usec = outResult->tv_usec + 1000000 - rhs.tv_usec;
		outResult->tv_sec = outResult->tv_sec - 1 - rhs.tv_sec;
	}
	
	while (outResult->tv_usec >= 1000000)
	{
		outResult->tv_sec++;
		outResult->tv_usec -= 1000000;
	}
}



static
int
_CheckPacket (
	const _CTestPacket *	inPacket)
{
	int			size;
	uint16_t	fcs = _kFCSSeed;
	uint8_t *	packet = (uint8_t *) &inPacket->mHeader.mSize;
	uint8_t		byte;
	
	
	CHECK_BLOCK (inPacket, FALSE, "null _CTestPacket");
	
	for (
		size = ntohs (inPacket->mHeader.mSize) - sizeof (inPacket->mHeader.mFCS);
		size > 0; --size)
	{
		byte = *packet++;
		fcs = (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
	
	return (fcs == ntohs (inPacket->mHeader.mFCS));
}



static
size_t
_MakeTestPacket (
	bdaddr_t	inSource,
	uint32_t	inSent,
	uint32_t	inReceived,
	ssize_t		inMinPayload,
	ssize_t		inMaxPayload,
	_CTestPacket *	outPacket)
{
	ssize_t		range;
	ssize_t		size = inMinPayload;
	uint16_t	fcs = _kFCSSeed;
	int			offset;
	uint8_t *	packet = (uint8_t *) &outPacket->mHeader.mSize;
	uint8_t		byte;
	
	
	CHECK_BLOCK (outPacket, 0, "null _CTestPacket");
	
	if (size < 0)
	{
		size = 0;
	}
	
	else if (size > sizeof (outPacket->mPayload))
	{
		size = sizeof (outPacket->mPayload);
	}
	
	if (size > inMaxPayload)
	{
		size = inMaxPayload;
	}
	
	range = inMaxPayload - size;
	
	if (range > sizeof (outPacket->mPayload) - size)
	{
		range = sizeof (outPacket->mPayload) - size;
	}
	DEBUG_LOG_TRACE ("min = %ld  range = %ld", size, range);	
	
	if (range > 0)
	{
		size += rand () % (range + 1);
	}
	
	outPacket->mHeader.mSize = htons (size + sizeof (outPacket->mHeader));
	outPacket->mHeader.mSource = inSource;
	outPacket->mHeader.mSent = htonl (inSent);
	outPacket->mHeader.mReceived = htonl (inReceived);
	
	for (
		offset = sizeof (outPacket->mHeader.mFCS);
		offset < sizeof (outPacket->mHeader);
		offset++)
	{
		byte = *packet++;
		fcs = (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
	
	while (size > 0)
	{
		--size;
		byte = rand ();
		*packet++ = byte;
		fcs = (fcs >> 8) ^ fcstbl [(fcs ^ byte) & 0x00ff];
	}
	
	outPacket->mHeader.mFCS = htons (fcs);
	
	ASSERT (_CheckPacket (outPacket), 0, "_MakeTestPacket () failed _CheckPacket ()");
	
	return ntohs (outPacket->mHeader.mSize);
}



static
int
_GetPacket (
	int				inSocket,
	_CTestPacket *	outPacket)
{
	int			result = 0;
	uint8_t *	packet = (uint8_t *) outPacket;
	size_t		expected = sizeof (outPacket->mHeader);
	size_t		allowed = sizeof (*outPacket);
	size_t		received = 0;
	int			size;
	int			check;
	uint8_t		overflow [256];
	
	
	CHECK_BLOCK (outPacket, EINVAL, "null _CTestPacket");
	
	
	// Get packet header:
	
	do
	{
		size = read (inSocket, packet, expected - received);
		
		if (size > 0)
		{
			DEBUG_LOG_TRACE ("expected = %lu, received = %lu", expected, received);
			received += size;
			packet += size;
		}
	}
	while (size > 0  &&  received < expected);
	
	result = errno;
	
	if (size < 0)
	{
		if (sQuit  ||  result == ECONNRESET)
		{
			return result;
		}
		
		CHECK_RESULT (result, "read () failed");
		CHECK_RESULT (-1, "read () failed");
	}
	
	ASSERT (!(received < expected), EIO, "received less than expected");
	
	
	// Get payload:
	
	expected = ntohs (outPacket->mHeader.mSize);
	DEBUG_LOG_STATUS ("Rx:                                                    exp: %6lu", expected);
	
	if (expected < sizeof (*outPacket))
	{
		allowed = expected;
	}
	
	else
	{
		allowed = sizeof (*outPacket);
	}
	
	while (size > 0  &&  received < allowed)
	{
		DEBUG_LOG_TRACE ("allowed = %lu, received = %lu", allowed, received);
		size = read (inSocket, packet, allowed - received);
		
		if (size > 0)
		{
			received += size;
			packet += size;
		}
	}
	
	while (size > 0  &&  received < expected)
	{
		DEBUG_LOG_TRACE ("expected = %lu, received = %lu", expected, received);
		size = read (inSocket, overflow, sizeof (overflow));
		
		if (size > 0)
		{
			received += size;
			packet += size;
		}
	}
	
	DEBUG_LOG_TRACE ("expected = %lu, received = %lu", expected, received);
	result = errno;
	
	if (size < 0)
	{
		if (sQuit  ||  result == ECONNRESET)
		{
			return result;
		}
		
		CHECK_RESULT (result, "read () failed");
		CHECK_RESULT (-1, "read () failed");
	}
	
	ASSERT (!(received < expected), EIO, "received less than expected");
	ASSERT (!(received > expected), EIO, "received more than expected");
	
	if (size == 0)
	{
		return ECONNRESET;
	}
	
	return 0;
}



static
int
_Send (
	int				inSocket,
	const void *	inPacket,
	size_t			inSize,
	ssize_t			inHeaderSize)
{
	int					result = 0;
	const uint8_t *		packet = (const uint8_t *) inPacket;
	size_t				remaining;
	int					size = 0;
	
	
	ASSERT (inSize == 0  ||  packet != NULL, EINVAL, "null packet");
	
	if (inSize >= inHeaderSize  &&  inHeaderSize > 0)
	{
		size = write (inSocket, packet, inHeaderSize);
		
		if (size > 0)
		{
			inSize -= size;
			packet += size;
		}
		
		else
		{
			inSize = size;
		}
	}
	
	while (inSize > 0)
	{
		size = write (inSocket, packet, inSize);
		
		if (size > 0)
		{
			inSize -= size;
			packet += size;
		}
		
		else
		{
			inSize = size;
		}
	}
	
	result = errno;
	
	if (size < 0)
	{
		if (sQuit  ||  result == ECONNRESET)
		{
			return result;
		}
		
		CHECK_RESULT (result, "write () failed");
		CHECK_RESULT (-1, "write () failed");
	}
	
	return 0;
}



static
void *
_ReadThread (
	void *	arg)
{
	static _CTestPacket		sIn;
	int						sd = *(int *) arg;
	int						error = 0;
	struct timeval			start;
	struct timeval			end;
	time_t					usec = 0;
	ssize_t					rate;
	int						size;
	int						ok;
	const char *			check = "";
	char					sourceName [32];
	
	
	while (!sQuit)
	{
		rate = 0;
		gettimeofday (&start, NULL);
		
		error = _GetPacket (sd, &sIn);
		gettimeofday (&end, NULL);
		
		if (sQuit  ||  error == ECONNRESET)
		{
			return 0;
		}
		
		ASSERT ((error == 0), NULL, "_GetPacket () failed");
		
		ok = _CheckPacket (&sIn);
		
		if (ok)
		{
			sReceiveCount++;
			check = "";
		}
		
		else
		{
			check = "  fcs [FAILED]";
		}
		
		DEBUG_LOG_TRACE ("start: sec = %ld  usec = %ld", start.tv_sec, start.tv_usec);
		DEBUG_LOG_TRACE ("end: sec = %ld  usec = %ld", end.tv_sec, end.tv_usec);
		_timeval_sub (&end, &start, &end);
		DEBUG_LOG_TRACE ("dur: sec = %ld  usec = %ld", end.tv_sec, end.tv_usec);
		usec = (end.tv_sec * 1000000) + end.tv_usec;
		
		if (usec <= 0)
		{
			usec = 1;
		}
		
		ba2str (&sIn.mHeader.mSource, sourceName);
		size = ntohs (sIn.mHeader.mSize);
		
		DEBUG_LOG_STATUS (
			"Rx: src: %s  sent: %5lu  rcvd: %5lu  size: %6d%s",
			sourceName,
			ntohl (sIn.mHeader.mSent),
			ntohl (sIn.mHeader.mReceived),
			size,
			check);
		
/*		size += rate;
		rate = (((long long) size) * 8 * 1000000) / usec;
		
		DEBUG_LOG_STATUS (
			"RT:                                                   size: %6d   ms: %5ld  bps: %6ld",
			size,
			((usec + 500) / 1000),
			rate);
*/		
		sched_yield ();
	}
}



static
int
_LoopTest (
	int					inSocket,
	const _COptions *	inOptions)
{
	static _CTestPacket		sOut;
	pthread_t				rx;
	uint32_t				sent = 0;
	socklen_t				optsize;
	int						error = 0;
	int						mtu = 0;
	ssize_t					min;
	ssize_t					max;
	struct sockaddr_rc		me;
	struct timeval			start;
	struct timeval			end;
	time_t					usec = 0;
	ssize_t					rate;
	int						size;
	char					sourceName [32];
	
	
/*	optsize = sizeof (mtu);
	error = getsockopt (inSocket, SOL_IRLMP, IRTTP_MAX_SDU_SIZE, &mtu, &optsize);
	
	if (error == 0  &&  mtu > 0)
	{
		DEBUG_LOG_STATUS ("MTU = %d", mtu);
	}
	
	else
	{
		mtu = 0;
	}
*/	
	sReceiveCount = 0;
	
	error = pthread_create (&rx, NULL, _ReadThread, &inSocket);
	CHECK_RESULT (error, "pthread_create () failed");
	
	min = inOptions->mMinPayload;
	max = inOptions->mMaxPayload;
	
	if (max < 0)
	{
		if (min > mtu)
		{
			max = min;
		}
		
		else
		{
			if (mtu <= 0)
			{
				mtu = _kDefaultMTU;
				DEBUG_LOG_STATUS ("MTU unknown. Assuming %d", mtu);
			}
			
			max = mtu - sizeof (_CTestPacketHeader);
		}
	}
	
	optsize = sizeof (me);
	getsockname (inSocket, (struct sockaddr *) &me, &optsize);
	
	
	while (!sQuit)
	{
		size = _MakeTestPacket (me.rc_bdaddr, sent, sReceiveCount, min, max, &sOut);
		gettimeofday (&start, NULL);
		error = _Send (inSocket, &sOut, size, inOptions->mHeaderSize);
		
		if (sQuit  ||  error == ECONNRESET)
		{
			return 0;
		}
		
		CHECK_RESULT (error, "_Send () failed");
		
		sent++;
		
		ba2str (&sOut.mHeader.mSource, sourceName);
		
		DEBUG_LOG_STATUS (
			"Tx: src: %s  sent: %5lu  rcvd: %5lu  size: %6d",
			sourceName,
			ntohl (sOut.mHeader.mSent),
			ntohl (sOut.mHeader.mReceived),
			ntohs (sOut.mHeader.mSize));
		
		sched_yield ();
	}
	
	return 0;
}



static
int
_RfConnect (
	bdaddr_t			inPeer,
	const _COptions *	inOptions)
{
	int					error;
	int					sd = -1;
	struct sockaddr_rc	peer;
	char				peerName [32];
	int					size;
	char				buffer [2048];
	
	
	CHECK_BLOCK (inOptions, EINVAL, "null _COptions");

	memset (&peer, 0, sizeof (peer));
	peer.rc_family = AF_BLUETOOTH;
	peer.rc_bdaddr = inPeer;
	peer.rc_channel = inOptions->mChannel;
	
	sd = socket (PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	
	if (sd == -1)
	{
		CHECK_RESULT (errno, "socket () failed");
		CHECK_RESULT (-1, "socket () failed");
	}
	
	ba2str (&peer.rc_bdaddr, peerName);
	
	DEBUG_LOG_STATUS ("Connecting to [%s] CH [%d]...", peerName, ((int) peer.rc_channel));
	error = connect (sd, (const struct sockaddr *) (&peer), sizeof (peer));
	
	if (error != 0)
	{
		close (sd);
		CHECK_RESULT (errno, "connect () failed");
		CHECK_RESULT (-1, "connect () failed");
	}
	
	DEBUG_LOG_STATUS ("Connected");
	
	error = _LoopTest (sd, inOptions);
	
	if (error != 0)
	{
		close (sd);
		CHECK_RESULT (error, "_LoopTest () failed");
	}
	
	DEBUG_LOG_STATUS ("Disconnected");
	close (sd);
	
	return 0;
}



static
int
_OnIsPrimaryModule (
	int		inSocket,
	int		inDeviceID,
	long	inContext)
{
	
	struct hci_dev_info		info;
	
	
	(void) inContext;
	
	DEBUG_LOG_TRACE ("_OnIsPrimaryModule (%d)", inDeviceID);
	if (hci_devinfo (inDeviceID, &info) != 0)
	{
		return FALSE;
	}
	
	DEBUG_LOG_TRACE ("_OnIsPrimaryModule: %s", info.name);
	return ((info.flags & _kPrimaryModuleFlags) == _kPrimaryModuleFlags);
}



static
int
_RfGetPrimaryBDA (
	bdaddr_t *	outBDA)
{
	int		hci = -1;
	
	
	CHECK_BLOCK (outBDA, EINVAL, "null bdaddr_t");
	
	hci = hci_for_each_dev (HCI_UP, _OnIsPrimaryModule, 0L);
	ASSERT ((hci >= 0), ENODEV, "No bluetooth modules");
	
	ASSERT ((hci_devba (hci, outBDA) == 0), errno, "hci_devba () failed");
	return 0;
}



static
int
_RfListen (
	const _COptions *	inOptions)
{
	int					error;
	int					listener = -1;
	struct sockaddr_rc	local;
	bdaddr_t			primary;
	char				localName [32];
	struct sockaddr_rc	peer;
	char				peerName [32];
	int					connection;
	socklen_t			size = 0;
	
	
	CHECK_BLOCK (inOptions, EINVAL, "null _COptions");
	
	memset (&local, 0, sizeof (local));
	local.rc_family = AF_BLUETOOTH;
	local.rc_bdaddr = *BDADDR_ANY;
	local.rc_channel = inOptions->mChannel;
	
	listener = socket (PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	
	if (listener == -1)
	{
		CHECK_RESULT (errno, "socket () failed");
		CHECK_RESULT (-1, "socket () failed");
	}
	
	error = bind (listener, (const struct sockaddr *) &local, sizeof (local));
	
	if (error != 0)
	{
		close (listener);
		CHECK_RESULT (errno, "connect () failed");
		CHECK_RESULT (-1, "connect () failed");
	}
	
	error = listen (listener, 1);
	
	if (error != 0)
	{
		close (listener);
		CHECK_RESULT (errno, "listen () failed");
		CHECK_RESULT (-1, "listen () failed");
	}
	
	size = sizeof (local);
	getsockname (listener, (struct sockaddr *) &local, &size);
	CHECK_RESULT (_RfGetPrimaryBDA (&primary), "_RfGetPrimaryBDA () failed");
	ba2str (&primary, localName);
	DEBUG_LOG_STATUS (
		"Waiting for connection to [%s] CH [%d]...", localName,
		((int) local.rc_channel));
	
	size = sizeof (peer);
	connection = accept (listener, (struct sockaddr *) &peer, &size);
	error = errno;
	close (listener);
	
	if (connection == -1)
	{
		if (sQuit)
		{
			return 0;
		}
		
		CHECK_RESULT (error, "accept () failed");
		CHECK_RESULT (-1, "accept () failed");
	}
	
	DEBUG_LOG_STATUS ("Connected");
	
	error = _LoopTest (connection, inOptions);
	
	if (error != 0)
	{
		close (connection);
		CHECK_RESULT (error, "_LoopTest () failed");
	}
	
	DEBUG_LOG_STATUS ("Disconnected");
	close (connection);
	
	return 0;
}



static
uint32_t
_GetPeer (
	void)
{
	int				sd = -1;
	_CDiscoveryLog	log;
	socklen_t		size = sizeof (log);
	int				index;
	
	
	sd = socket (AF_IRDA, SOCK_SEQPACKET, 0);
	ASSERT (sd != -1, 0, "socket () failed");
	
	memset (&log, 0, sizeof (log));
	
	if (getsockopt (sd, SOL_IRLMP, IRLMP_ENUMDEVICES, &log, &size) != 0)
	{
		ASSERT (FALSE, 0, "getsockopt (IRLMP_ENUMDEVICES) failed");
	}
	
	close (sd);
	
	for (index = 0; index < log.mHeader.len; index++)
	{
		if (log.mHeader.dev [index].daddr != 0)
		{
			DEBUG_LOG_STATUS ("Found \"%s\"", log.mHeader.dev [index].info);
			return log.mHeader.dev [index].daddr;
		}
	}
	
	DEBUG_LOG_STATUS ("no devices");
	return 0;
}



static
void
_OnSIGINT (
	int				signo,
	siginfo_t *		info,
	void *			context)
{
	if (sQuit > 1)
	{
		sigaction (SIGINT, &sOnSIGINT, NULL);
	}
	
	sQuit++;
}



static
void
_PrintUsage (
	const char	inName [])
{
	const char *	parse;
	
	
	for (parse = inName; *parse != '\0'; parse++)
	{
		if (*parse == '/')
		{
			parse++;
			
			if (*parse == '\0')
			{
				break;
			}
			
			inName = parse;
		}
	}
	
	fprintf (
		stderr,
		"Usage: %s -c <channel> [OPTION]... [TARGET_BDA]\n"
		"Send and receive RFCOMM messages in the following format.  Offsets and sizes\n"
		"are in octets, and field values are in network byte order.\n"
		"\n"
		"OFFSET       SIZE   FIELD\n"
		"     0          2   FCS        RFC 1171 CRC from next field to end of message\n"
		"     2          2   Size       Size of message from offset 0 to end of message\n"
		"     4          6   Source     IrLAP address of message originator\n"
		"    10          4   Sent       Number of messages origniator sent before this\n"
		"    14          4   Received   Number of valid messages originator has received\n"
		"    18  Size - 18   Payload    Random data.  The payload size varies randomly\n"
		"                               within the range determined by -m, -M, and -p\n"
		"                               options or their defaults.\n"
		"\n"
		"\n"
		"A -c option is required.\n"
		"\n"
		"Protocol Options:\n"
		"  -c <channel>   client mode, where <channel> is the RFCOMM channel to\n"
		"                 which to connect.  Overrides any previous -c options.\n"
		"\n"
		"Data Options:\n"
		"  -m <size>      minimum payload size.  Overrides any previous -m or -p\n"
		"                 options. [Default: 0]\n"
		"  -M <size>      maximum payload size.  Overrides any previous -M or -p\n"
		"                 options. [Default: fit to MTU]\n"
		"  -p <size>      exact payload size.  Overrides any previous -m or -M\n"
		"                 options. [Default: see -m and -M]\n"
		"  -H <size>      send each message as a header of <size> bytes followed by\n"
		"                 the rest of the message [Default: 0]\n"
		, inName
	);
}



int
main (
	int				argc,
	char * const	argv [])
{
	static const char	sOptionList [] = {
							_kOptRFCOMMChannel, _kOptTakesArgument,
//							_kOptEcho,
							_kOptHeaderSize, _kOptTakesArgument,
							_kOptMinPayload, _kOptTakesArgument,
							_kOptMaxPayload, _kOptTakesArgument,
							_kOptPayloadSize, _kOptTakesArgument,
							_kOptReverseRole
						};
	struct sigaction	action;
	unsigned			seed = time (NULL);
	_COptions			options;
	int					opt;
	const char *		arg = NULL;
	int					reverse = FALSE;
	int					error;
	bdaddr_t			rfPeer;
	
	
	action.sa_handler = NULL;
	action.sa_flags = SA_SIGINFO;
	action.sa_sigaction = _OnSIGINT;
	sigemptyset (&action.sa_mask);
	
//	sigaction (SIGINT, &action, &sOnSIGINT);
	
	memset (&options, 0, sizeof (options));
	options.mMaxPayload = -1; // mtu
	
	do
	{
		opt = getopt (argc, argv, sOptionList);
		
		if (optarg != NULL  &&  optarg [0] == '=')
		{
			arg = optarg + 1;
		}
		
		else
		{
			arg = optarg;
		}
		
		switch (opt)
		{
			case _kOptMaxPayload:
			{
				options.mMaxPayload = strtoul (arg, NULL, 0);
			}
			break;
			
			
			case _kOptEcho:
			{
				options.mEcho = TRUE;
			}
			break;
			
			
			case _kOptHeaderSize:
			{
				options.mHeaderSize = strtoul (arg, NULL, 0);
			}
			break;
			
			
			case _kOptReverseRole:
			{
				reverse = !reverse;
			}
			break;
			
			
			case _kOptMinPayload:
			{
				options.mMinPayload = strtoul (arg, NULL, 0);
			}
			break;
			
			
			case _kOptPayloadSize:
			{
				options.mMinPayload = strtoul (arg, NULL, 0);
			}
			break;
			
			
			case _kOptRFCOMMChannel:
			{
				options.mChannel = strtoul (arg, NULL, 0);
			}
			break;
		}
	}
	while (opt != -1);
	
	
	if (options.mChannel == 0)
	{
		_PrintUsage (argv [0]);
		return 1;
	}
	
	if (optind < argc)
	{
		if (str2ba (argv [argc - 1], &rfPeer) != 0)
		{
			_PrintUsage (argv [0]);
			return 1;
		}
		
		options.mIsClient = TRUE;
	}
	
	if (reverse)
	{
		options.mIsInitiator = !options.mIsClient;
	}
	
	else
	{
		options.mIsInitiator = options.mIsClient;
	}
	
	srand (seed);
	DEBUG_LOG_STATUS ("Random seed = %u", seed);
	
	
	while (!sQuit)
	{
		if (options.mIsClient)
		{
			_RfConnect (rfPeer, &options);
			
			sleep (3);
		}
		
		else
		{
			error = _RfListen (&options);
			CHECK_RESULT (error, "_RfListen () failed");
		}
	}
	
	return 0;
}

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 16:13   ` Brand, Chris
@ 2006-05-29 17:36     ` Marcel Holtmann
  2006-05-29 17:57       ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 17:36 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > please send the code as attachment. It seems your mailer 
> > messed up the whitespaces.
> 
> Attached. Sorry about that.
> 
> > How do I run the test case 
> > and what should I look for?
> 
> On one node, I run it with "./rfcommloop -c 1 -M 1024". It reports the
> bluetooth address of the device it's using. On the other node, use the
> same command line but append the reported bluetooth address.

it doesn't actually work (and yes, a dongle is attached):

# ./rfcommloop -c 1 -M 1024
[Status] Random seed = 1148924068
_RfGetPrimaryBDA [757]: No bluetooth modules (19)
_RfGetPrimaryBDA [757]: No bluetooth modules (19)
_RfListen [816]: _RfGetPrimaryBDA () failed (19)
_RfGetPrimaryBDA [757]: No bluetooth modules (19)
main [1117]: _RfListen () failed (19)

Are you sure this is the latest code?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 17:36     ` Marcel Holtmann
@ 2006-05-29 17:57       ` Brand, Chris
  2006-05-29 18:44         ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 17:57 UTC (permalink / raw)
  To: BlueZ development


> it doesn't actually work (and yes, a dongle is attached):

That's very strange.

> Are you sure this is the latest code?

I just rebuilt and re-ran it here and it ran fine.

It must depend on some other setup thing, but I'm not sure what...
"hcitool dev" lists your dongle, I presume ? (talk about teaching your
grandmother to suck eggs :-))

What you listed is the output I get after disconnecting my dongle.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 17:57       ` Brand, Chris
@ 2006-05-29 18:44         ` Marcel Holtmann
  2006-05-29 18:48           ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 18:44 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > it doesn't actually work (and yes, a dongle is attached):
> 
> That's very strange.
> 
> > Are you sure this is the latest code?
> 
> I just rebuilt and re-ran it here and it ran fine.

you need to attach at least two dongles to make your program work. Is
this really what it is supposed to do?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 18:44         ` Marcel Holtmann
@ 2006-05-29 18:48           ` Brand, Chris
  2006-05-29 19:00             ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 18:48 UTC (permalink / raw)
  To: BlueZ development

 
> you need to attach at least two dongles to make your program 
> work. Is this really what it is supposed to do?

One dongle to each of two machines, yes (I haven't tried it with one
machine and two dongles, but don't see why it shouldn't work).

The idea is to pass data back and forth between two machines over
bluetooth.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 18:48           ` Brand, Chris
@ 2006-05-29 19:00             ` Marcel Holtmann
  2006-05-29 19:01               ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 19:00 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

>  > you need to attach at least two dongles to make your program 
> > work. Is this really what it is supposed to do?
> 
> One dongle to each of two machines, yes (I haven't tried it with one
> machine and two dongles, but don't see why it shouldn't work).

no, you need two dongles on one machine to make your code work. It
actually picks hci1 and not hci0.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 19:00             ` Marcel Holtmann
@ 2006-05-29 19:01               ` Brand, Chris
  2006-05-29 20:21                 ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 19:01 UTC (permalink / raw)
  To: BlueZ development

 
> no, you need two dongles on one machine to make your code 
> work. It actually picks hci1 and not hci0.

I only have one dongle attached to the machine I ran it on this morning.
"hcitool dev" only lists hci0.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 19:01               ` Brand, Chris
@ 2006-05-29 20:21                 ` Marcel Holtmann
  2006-05-29 20:33                   ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 20:21 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

>  > no, you need two dongles on one machine to make your code 
> > work. It actually picks hci1 and not hci0.
> 
> I only have one dongle attached to the machine I ran it on this morning.
> "hcitool dev" only lists hci0.

this is strange. What version of bluez-libs do you use?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 20:21                 ` Marcel Holtmann
@ 2006-05-29 20:33                   ` Brand, Chris
  2006-05-29 20:37                     ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 20:33 UTC (permalink / raw)
  To: BlueZ development

 
> this is strange. What version of bluez-libs do you use?

This is a FC4 machine.
Yum reports that it's using bluez-libs 2.15-1.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 20:33                   ` Brand, Chris
@ 2006-05-29 20:37                     ` Marcel Holtmann
  2006-05-29 20:39                       ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-29 20:37 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

>  > this is strange. What version of bluez-libs do you use?
> 
> This is a FC4 machine.
> Yum reports that it's using bluez-libs 2.15-1.

that might be the reason. We fixed a lot of stuff between the 2.15 and
2.25. Do you mind updating to FC5? Your code seems to work by accident.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 20:37                     ` Marcel Holtmann
@ 2006-05-29 20:39                       ` Brand, Chris
  2006-05-31 18:08                         ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-29 20:39 UTC (permalink / raw)
  To: BlueZ development

> that might be the reason. We fixed a lot of stuff between the 
> 2.15 and 2.25. Do you mind updating to FC5?

That's been on my to-do list for a while. Now I seem to have a good
reason to get on with it :-)

> Your code seems 
> to work by accident.

I hate it when that happens :-)

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-29 20:39                       ` Brand, Chris
@ 2006-05-31 18:08                         ` Brand, Chris
  2006-05-31 20:08                           ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-05-31 18:08 UTC (permalink / raw)
  To: BlueZ development


> > that might be the reason. We fixed a lot of stuff between the
> > 2.15 and 2.25. Do you mind updating to FC5?
> 
> That's been on my to-do list for a while. Now I seem to have 
> a good reason to get on with it :-)

I've upgraded one of the two machines to FC5 (bluez-libs 2.25-1), and my
test code is quite happy to run with only one bt dongle attached.

Still have to upgrade the other machine to see whether the symptoms I
observed are still present with the newer bluez stack.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-31 18:08                         ` Brand, Chris
@ 2006-05-31 20:08                           ` Marcel Holtmann
  2006-06-01 16:55                             ` Brand, Chris
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-05-31 20:08 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > > that might be the reason. We fixed a lot of stuff between the
> > > 2.15 and 2.25. Do you mind updating to FC5?
> > 
> > That's been on my to-do list for a while. Now I seem to have 
> > a good reason to get on with it :-)
> 
> I've upgraded one of the two machines to FC5 (bluez-libs 2.25-1), and my
> test code is quite happy to run with only one bt dongle attached.

even with the latest FC5 kernel?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-05-31 20:08                           ` Marcel Holtmann
@ 2006-06-01 16:55                             ` Brand, Chris
  2006-06-01 17:54                               ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-06-01 16:55 UTC (permalink / raw)
  To: BlueZ development

> > I've upgraded one of the two machines to FC5 (bluez-libs 
> 2.25-1), and 
> > my test code is quite happy to run with only one bt dongle attached.
> 
> even with the latest FC5 kernel?

No. Now I see the same thing you do.
Something changed here between kernel 2.6.15 and 2.6.16, then ?

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
@ 2006-06-01 17:01 Brand, Chris
  2006-06-01 17:56 ` Marcel Holtmann
  2006-06-01 21:11 ` Marcel Holtmann
  0 siblings, 2 replies; 24+ messages in thread
From: Brand, Chris @ 2006-06-01 17:01 UTC (permalink / raw)
  To: BlueZ development

 
> > > I've upgraded one of the two machines to FC5 (bluez-libs
> > 2.25-1), and
> > > my test code is quite happy to run with only one bt 
> dongle attached.
> > 
> > even with the latest FC5 kernel?
> 
> No. Now I see the same thing you do.

I take that back - sorry.

I actually didn't have a dongle attached. With a single dongle attached,
my test code does still start fine.

Kernel is 2.6.16-1.2122_FC5smp (from cat /proc/version)
I've also got these installed :
bluez-hcidump.i386 1.30-1
bluez-libs.i386 2.25-1
bluez-libs-devel.i386 2.25-1
bluez-pin.i386 0.30-2
bluez-utils.i386 2.25-4
(all from yum list bluez\*)

Basically, this is a fully-updated FC5.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 16:55                             ` Brand, Chris
@ 2006-06-01 17:54                               ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2006-06-01 17:54 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > > I've upgraded one of the two machines to FC5 (bluez-libs 
> > 2.25-1), and 
> > > my test code is quite happy to run with only one bt dongle attached.
> > 
> > even with the latest FC5 kernel?
> 
> No. Now I see the same thing you do.
> Something changed here between kernel 2.6.15 and 2.6.16, then ?

then it is the socket fix. You are trying to run a getsockname() on an
unbound socket.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 17:01 [Bluez-devel] Strange behaviour Brand, Chris
@ 2006-06-01 17:56 ` Marcel Holtmann
  2006-06-01 21:11 ` Marcel Holtmann
  1 sibling, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2006-06-01 17:56 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > > even with the latest FC5 kernel?
> > 
> > No. Now I see the same thing you do.
> 
> I take that back - sorry.
> 
> I actually didn't have a dongle attached. With a single dongle attached,
> my test code does still start fine.
> 
> Kernel is 2.6.16-1.2122_FC5smp (from cat /proc/version)
> I've also got these installed :
> bluez-hcidump.i386 1.30-1
> bluez-libs.i386 2.25-1
> bluez-libs-devel.i386 2.25-1
> bluez-pin.i386 0.30-2
> bluez-utils.i386 2.25-4
> (all from yum list bluez\*)
> 
> Basically, this is a fully-updated FC5.

then it must be the bluez-libs from CVS.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 17:01 [Bluez-devel] Strange behaviour Brand, Chris
  2006-06-01 17:56 ` Marcel Holtmann
@ 2006-06-01 21:11 ` Marcel Holtmann
  2006-06-01 21:16   ` Brand, Chris
  1 sibling, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-06-01 21:11 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > > even with the latest FC5 kernel?
> > 
> > No. Now I see the same thing you do.
> 
> I take that back - sorry.
> 
> I actually didn't have a dongle attached. With a single dongle attached,
> my test code does still start fine.

I hacked up the code to avoid this test and simply go ahead with hci0
and I can see that something weird is going on. However I have no idea
what it is and your code is not easy to follow.

Do you really need to use a thread to produce this behavior. I normally
try to avoid any threaded programs at all. Can you please remove all
extra stuff from your code (and use simply hci0 only) and try to not to
use threads?

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 21:11 ` Marcel Holtmann
@ 2006-06-01 21:16   ` Brand, Chris
  2006-06-01 22:55     ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brand, Chris @ 2006-06-01 21:16 UTC (permalink / raw)
  To: BlueZ development

> Do you really need to use a thread to produce this behavior. 
> I normally try to avoid any threaded programs at all. Can you 
> please remove all extra stuff from your code (and use simply 
> hci0 only) and try to not to use threads?
> 

I think the problem only occurs when I'm sending and receiving at the
same time, which could well mean that it will only occur with a threaded
program.

Chris


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 21:16   ` Brand, Chris
@ 2006-06-01 22:55     ` Marcel Holtmann
  2006-06-01 23:01       ` Brad Midgley
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2006-06-01 22:55 UTC (permalink / raw)
  To: BlueZ development

Hi Chris,

> > Do you really need to use a thread to produce this behavior. 
> > I normally try to avoid any threaded programs at all. Can you 
> > please remove all extra stuff from your code (and use simply 
> > hci0 only) and try to not to use threads?
> 
> I think the problem only occurs when I'm sending and receiving at the
> same time, which could well mean that it will only occur with a threaded
> program.

can we try to reproduce this with a non-thread test program. If we can
reproduce it this way, it will be much easier to debug.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 22:55     ` Marcel Holtmann
@ 2006-06-01 23:01       ` Brad Midgley
  2006-06-01 23:11         ` Marcel Holtmann
  0 siblings, 1 reply; 24+ messages in thread
From: Brad Midgley @ 2006-06-01 23:01 UTC (permalink / raw)
  To: BlueZ development

Marcel

> can we try to reproduce this with a non-thread test program. If we can
> reproduce it this way, it will be much easier to debug.

maybe using async socket i/o would reproduce it.

threads implementations and debugging threads has improved from the bad
old days but I can understand the desire to avoid the issue.

brad


_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Bluez-devel] Strange behaviour
  2006-06-01 23:01       ` Brad Midgley
@ 2006-06-01 23:11         ` Marcel Holtmann
  0 siblings, 0 replies; 24+ messages in thread
From: Marcel Holtmann @ 2006-06-01 23:11 UTC (permalink / raw)
  To: BlueZ development

Hi Brad,

> > can we try to reproduce this with a non-thread test program. If we can
> > reproduce it this way, it will be much easier to debug.
> 
> maybe using async socket i/o would reproduce it.
> 
> threads implementations and debugging threads has improved from the bad
> old days but I can understand the desire to avoid the issue.

I actually like to find an easy way to reproduce it, because waiting for
the luck of some scheduling is not funny. I need to understand when this
issue happens before I can actually fix it.

Regards

Marcel




_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2006-06-01 23:11 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-01 17:01 [Bluez-devel] Strange behaviour Brand, Chris
2006-06-01 17:56 ` Marcel Holtmann
2006-06-01 21:11 ` Marcel Holtmann
2006-06-01 21:16   ` Brand, Chris
2006-06-01 22:55     ` Marcel Holtmann
2006-06-01 23:01       ` Brad Midgley
2006-06-01 23:11         ` Marcel Holtmann
  -- strict thread matches above, loose matches on Subject: below --
2006-05-17 17:51 Brand, Chris
2006-05-29 13:22 ` Marcel Holtmann
2006-05-29 16:13   ` Brand, Chris
2006-05-29 17:36     ` Marcel Holtmann
2006-05-29 17:57       ` Brand, Chris
2006-05-29 18:44         ` Marcel Holtmann
2006-05-29 18:48           ` Brand, Chris
2006-05-29 19:00             ` Marcel Holtmann
2006-05-29 19:01               ` Brand, Chris
2006-05-29 20:21                 ` Marcel Holtmann
2006-05-29 20:33                   ` Brand, Chris
2006-05-29 20:37                     ` Marcel Holtmann
2006-05-29 20:39                       ` Brand, Chris
2006-05-31 18:08                         ` Brand, Chris
2006-05-31 20:08                           ` Marcel Holtmann
2006-06-01 16:55                             ` Brand, Chris
2006-06-01 17:54                               ` Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).