Click to See Complete Forum and Search --> : Bluetooth socket - data receive error


csienke
April 24th, 2008, 02:48 PM
Hi, I wrote a Bluetooth socket application (server and client), but I have a strange error.
I can send data from the client to the server, but when I want to send something from the server to the client I got 10093 error on the client part.
It is strange, because I initialized the WSAStartup and I could send data to the server.

Can somebody help me please?

MikeAThon
April 25th, 2008, 09:55 AM
There's no way around this. 10093 is WSANOTINITIALISED. Either your application hasn't called WSAStartup, or it called WSAStartup but the call failed.

Are you certain that you called WSAStartup? Are you certain that it didn't fail?

Mike

csienke
April 25th, 2008, 11:26 AM
Yes, I called WSAStartup. And it didn't fail.
I wrote a thread class, and I wanted to receive the data there. My Bluetooth socket is created in a class too (BTClientSocket class). So I called WSAStartup there.
I know that WSAStartup must be called only one time, but I tried to resolve this error and I initialized WSAStartup in my thread too before I receive the data. Than I got 10038 error (the descriptor is not a socket). I don't understand this.
If you have any suggestions how to resolve this error, please reply. Thank you.

csienke
April 25th, 2008, 11:29 AM
I tried to send data from the server to the client with the SDK sample application too. There I got the following error: Data transfer aborted mid-stream. Expected Length = [100], Actual Length = [0]

MikeAThon
April 25th, 2008, 01:01 PM
Post the code that's failing. Please also give us the following information:

1. The returned value of each socket function, and the value of WSAGetLastError() for each socket function that returned a value that was not expected.

2. The name of the OS your code is running under, and a brief description of the machine (for example, is it a handheld with Win CE?)

3. The name of the BlueTooth interface (brand and model).

Mike

csienke
April 26th, 2008, 10:15 AM
Here is my code:

1.
Version 1:
------------
Client side code (BTClient):

int main(int argc , char* argv[])
{
CBTClientSocket btsock;

if (!btsock.InitSocket())
{
printf("WSAStartup error\n");
return 0;
}

// parse the specified Bluetooth address
if (argc < 2)
{
fprintf(stderr, "usage: rfcomm-client <addr>\n"
"\n addr must be in the form

(XX:XX:XX:XX:XX:XX)");
return 0;
}

if (!btsock.CreateSocket())
{
printf("Socket creation failed, error %d\n", WSAGetLastError());
return 0;
}

if (!btsock.MakeConnection(argv[1]))
{
printf("Socket connect error %d\n", WSAGetLastError());
return 0;
}

SOCKET sock = btsock.GetSocket();
send(sock, "hello!", 6, 0);

MyThread* szal = new MyThread(sock);

try{
szal->start();
}
catch (CreateThreadError)
{
printf("Create thread error.\n");
};

btsock.CloseConnection();
}

bool CBTClientSocket::InitSocket()
{
// initialize windows sockets
WORD wVersionRequested;
WSADATA wsaData;

wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
//printf("WSAStartup error\n");
return false;
}

return true;
}

bool CBTClientSocket::CreateSocket()
{
// create the socket
sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if (SOCKET_ERROR == sock)
{
//printf("Socket creation failed, error %d\n", WSAGetLastError());
return false;
}

return true;
}

bool CBTClientSocket::FillSockAddress(const char* addr)
{
int sa_len = sizeof(sa);

if (SOCKET_ERROR == WSAStringToAddress(const_cast<char*>(addr), AF_BTH, NULL,

(LPSOCKADDR)&sa, &sa_len))
{
printf("WSAStringToAddress error %d\n", WSAGetLastError());
return false;
}

// fill in the rest of the SOCKADDR_BTH struct
sa.port = SDPGetPort(addr, (LPGUID)&SAMPLE_UUID);
if (sa.port == 0)
{
printf("SDPGetPort error\n");
return false;
}

return true;
}

bool CBTClientSocket::MakeConnection(const char* addr)
{
int sa_len = sizeof(sa);

if (!FillSockAddress(addr))
return false;

if (SOCKET_ERROR == connect(sock, (LPSOCKADDR)&sa, sa_len))
{
//printf("Socket connect error %d\n", WSAGetLastError());
return false;
}

return true;
}

int CBTClientSocket::SDPGetPort(const char *addr, LPGUID guid)
{
int port = 0;
HANDLE h;
WSAQUERYSET *qs;
DWORD flags = 0;
DWORD qs_len;
bool done;

qs_len = sizeof(WSAQUERYSET);
qs = (WSAQUERYSET* )malloc(qs_len);
ZeroMemory(qs, qs_len);
qs->dwSize = sizeof(WSAQUERYSET);
qs->lpServiceClassId = guid;
qs->dwNameSpace = NS_BTH;
qs->dwNumberOfCsAddrs = 0;
qs->lpszContext = (LPSTR) addr;
flags = LUP_FLUSHCACHE | LUP_RETURN_ADDR;

if (SOCKET_ERROR == WSALookupServiceBegin(qs , flags, &h))
{
return -1;
}

done = false;
while (!done)
{
if (SOCKET_ERROR == WSALookupServiceNext(h, flags, &qs_len, qs))
{
int error = WSAGetLastError();
if (error == WSAEFAULT)
{
free(qs);
qs = (WSAQUERYSET* )malloc(qs_len);
} else
if (error == WSA_E_NO_MORE)
{
done = true;
} else
{
return -1;
}
} else
{
SOCKADDR_BTH *sa = (SOCKADDR_BTH* )qs->lpcsaBuffer-

>RemoteAddr.lpSockaddr;
port = sa->port;
}
}

free(qs);
WSALookupServiceEnd(h);

return port;
}

void MyThread::run()
{
int received = 0;
char recvbuf[BUFF_SIZE];
int recvbuflen = BUFF_SIZE;

do {

received = recv(m_socket, recvbuf, recvbuflen, 0);
if ( received > 0 )
{
recvbuf[received]='\0';
printf( "received: %s\n", recvbuf);
//printf("Bytes received: %d\n", iResult);


}
else if ((received == SOCKET_ERROR) && (WSAGetLastError () ==

WSAEWOULDBLOCK))
{
//wait
received = 0;
Sleep(10);
}
else if ( received == 0 )
{
//printf("Connection closed\n");
}
else
{
printf("recv failed: %d\n", WSAGetLastError());
return;
}
} while (( received > 0 )&& running );
}


Server side code:

int main(int argc, char* argv[])
{
CBTServerSocket btsock;

if (btsock.InitSocket())
{
if (btsock.CreateListenSocket())
{
if (btsock.BindSocket())
{
if (!btsock.ListenToSocket())
{
printf("Error listening on socket: %d\n",

WSAGetLastError());
}
else
{
int port = btsock.GetListenPort();
if (port > 0)
{
printf("Listening on RFCOMM port: %d\n",

port);
}
else
printf("Getsockname error %d\n",

WSAGetLastError());

if (!btsock.ServiceAdvertise())
printf("WSASetService() error %d\n",

WSAGetLastError());
}
}
else
printf("Socket bind() error %d\n", WSAGetLastError());
}
else
printf("Socket creation failed, error %d\n", WSAGetLastError());
}
else
printf("WSAStartup() error\n");


char* buf = new char[1025];

while (!kbhit())
{
if (btsock.CreateAcceptSocket())
{

MyThread* szal = new MyThread(btsock.GetAcceptSocket());

try{
szal->start();
}
catch (CreateThreadError)
{
printf("Create thread error.\n");
};

Sleep(100);
}
else{
//printf("accept() failed: %d\n", WSAGetLastError());
printf("Socket accept, error %d\n", WSAGetLastError());
}
}

btsock.CloseConnection();
delete[] buf;

return 0;
}

bool CBTServerSocket::InitSocket()
{
// initialize windows sockets
WORD wVersionRequested;
WSADATA wsaData;

wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
//printf("WSAStartup error\n");
return false;
}

return true;
}

bool CBTServerSocket::CreateListenSocket()
{
// create the server socket
server = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if (SOCKET_ERROR == server)
{
//printf("Socket creation failed, error %d\n", WSAGetLastError());
return false;
}

return true;
}

bool CBTServerSocket::BindSocket()
{
// bind the server socket to an arbitrary RFCOMM port
sa.addressFamily = AF_BTH;
sa.btAddr = 0;
sa.port = BT_PORT_ANY;

if (SOCKET_ERROR == bind (server, (const sockaddr*)&sa, sizeof(SOCKADDR_BTH)))
{
//printf("Socket bind, error %d\n", WSAGetLastError ());
closesocket(server);
return false;
}

return true;
}

bool CBTServerSocket::ListenToSocket()
{
//listen to the socket
if (SOCKET_ERROR == listen(server, 1))
{
//printf("Socket listen, error %d\n", WSAGetLastError ());
closesocket(server);
return false;
}

return true;
}

int CBTServerSocket::GetListenPort()
{
int sa_len = sizeof(sa);

// check which port we’re listening on
if (SOCKET_ERROR == getsockname (server, (SOCKADDR*)&sa, &sa_len))
{
//printf("Getsockname error %d\n", WSAGetLastError ());
closesocket(server);
return -1;
}
//printf("Listening on RFCOMM port: %d\n", sa.port);
return sa.port;
}

bool CBTServerSocket::ServiceAdvertise()
{
// advertise the service
CSADDR_INFO sockInfo;
sockInfo.iProtocol = BTHPROTO_RFCOMM;
sockInfo.iSocketType = SOCK_STREAM;
sockInfo.LocalAddr.lpSockaddr = (LPSOCKADDR)&sa;
sockInfo.LocalAddr.iSockaddrLength = sizeof(sa);
sockInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR)&sa;
sockInfo.RemoteAddr.iSockaddrLength = sizeof(sa);

WSAQUERYSET svcInfo = {0};
svcInfo.dwSize = sizeof(svcInfo);
svcInfo.dwNameSpace = NS_BTH;
svcInfo.lpszServiceInstanceName = "Win32 Sample Bluetooth Service";
svcInfo.lpszComment = "Description of service...";
svcInfo.lpServiceClassId = (LPGUID)&SAMPLE_UUID;
svcInfo.dwNumberOfCsAddrs = 1;
svcInfo.lpcsaBuffer = &sockInfo;

if (SOCKET_ERROR == WSASetService(&svcInfo, RNRSERVICE_REGISTER, 0))
{
//printf("WSASetService error %d\n", WSAGetLastError ());
closesocket(server);
return false;
}

return true;
}

bool CBTServerSocket::CreateAcceptSocket()
{
int ca_len = sizeof(ca);

char buf[1024] = {0};
DWORD buf_len = sizeof(buf);

client = accept(server, (LPSOCKADDR)&ca, &ca_len);
if (SOCKET_ERROR == client)
{
//printf("Socket accept, error %d\n", WSAGetLastError ());
closesocket(server);
return false;
}

WSAAddressToString((LPSOCKADDR)&ca, (DWORD)ca_len, NULL, buf, &buf_len);

return true;
}

void MyThread::run()
{
int received = 0;
char recvbuf[BUFF_SIZE];
int recvbuflen = BUFF_SIZE;

do {

received = recv(m_socket, recvbuf, recvbuflen, 0);
printf( "received: %d\n", received);

if ( received > 0 )
{
recvbuf[received]='\0';
printf( "received: %s\n", recvbuf);
//printf("Bytes received: %d\n", iResult);

int v = send(m_socket,"Data received",9,0);
printf("Sent: %d\n",v);

}
else if ((received == SOCKET_ERROR) && (WSAGetLastError () ==

WSAEWOULDBLOCK))
{
//wait
received = 0;
Sleep(10);
}
else if ( received == 0 )
{
//printf("Connection closed\n");
}
else
{
printf("recv failed: %d\n", WSAGetLastError());
return;
}
} while (( received > 0 )&& running );
}


Client program output:

received: -1
recv failed: 10093

Server program output:

Listening on RFCOMM port: 1
received: hello!
Sent: 9

Version 2:
----------
I modified the MyThread:run() on the client side and server side too:

void MyThread::run()
{
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
printf("Error at WSAStartup()\n");

//.....................

//The rest is the same (client side, server side).
}


Then I got the outputs:

Client side:

received: -1
recv failed: 10038

Server side:

Listening on RFCOMM port: 1
received: hello!
Sent: 9

2.
Computer 1: OS = Windows Vista Basic (laptop computer)
Computer 2: OS = Windows XP (desktop computer)

3.
Computer 1: Fujitsu Siemens Bluetooth USB Stick V2.0
Computer 2: Fujitsu Siemens Bluetooth USB Stick V2.0

MikeAThon
April 26th, 2008, 12:13 PM
I think your code is based on this partially-completed book from a pair of MIT professors: "Bluetooth for Programmers" at http://people.csail.mit.edu/rudolph/Teaching/Articles/BTBook-march.pdf

I had not seen that book before, so thanks for that.

Anyway, sad to say, I do not see anything apparent in the code you posted. And I can't explain the different results when WSAStartup is and is not called from the thread: As you say, the call to WSAStartup is process-based not thread-based, so it only needs calling once per program not once per thread.

It's probably worthwhile to look elsewhere. I would start with firewalls and LSPs. Disable all firewalls on both computers. Uninstall all unneeded LSPs. Restart the machines and try again.

In addition, in another thread ( http://www.codeguru.com/forum/showthread.php?p=1688625#post1688625 ) you indicated that you were using a Abe USB Bluetooth Dongle. Why have you changed? Does the code posted at that other thread still give good results for the "RfComm [Bluetooth]" protocol?

Mike

csienke
April 26th, 2008, 12:43 PM
Yes I used the book you mentioned.

I used the Abe USB dongle, but I had only one of it and it wasn't mine. It still gives good results for the "RfComm [Bluetooth]" protocol. In the meantime I got the Fujitsu Siemens dongles. They are good too. However, I borrowed the Abe dongle again to see if the 10093 error occures. And I got the same error when sending the data from the server to the client.

I don't know how it is possible because the server receives the data from the client.

I will try out your suggestions. Thank you for it. And thank you for your reply. After I try out, I will send a post.

I don't know what the LSPs are. Can you please explain to me?

MikeAThon
April 26th, 2008, 01:44 PM
"LSP" is "Layered Service Provider". The Windows TCP stack is designed to allow service providers to integrate themselves into the stack, in layers. This is usually how virus/spam protectors prevent malicious/spam from entering your computer via the Internet. This is a good thing. It is also how some trojans/virii install themselves into your system, which is a bad thing.

Faulty LSPs, even if written with goodintent, can often interfere with proper operation of your network. So, if you are getting odd results on your network, maybe it's a faulty LSP.

Search around for programs that will show you the LSPs that are installed on your systems. The platform SDK has one that you can build for yourself, called "SPORDER" (for service provider order). Another one is called LSP-Fix (see http://www.bleepingcomputer.com/tutorials/tutorial59.html ).

For each LSP you see, you should be able to match it against a program installed on your computer (like anti-virus or something). You should try uninstalling the associated program, and confirming that the LSP has also been removed, until you get down to a bare-bones stack.

Mike

csienke
April 27th, 2008, 03:54 AM
Hi again!

I tried out to disable all firewalls. I hadn't any LSPs installed. Unfortunately I got the same error.

Did anybody write a program that sends and receives Bluetooth data on server and client part too? If yes, which dongle did he/she used?