Bluetooth socket returns WSAEPROTONOSUPPORT - c++

For a project I am working on I would like to have an Embedded System to act as a Bluetooth server. I got the driver for my USb-Bluetooth working and in the Control Panel I now have a "Bluetooth Device Properties"-option which works and detects other devices via the Bluetooth USB dongle.
However when I try to use the dongle in code, I get an error.
The Includes are:
winsock2.h, ws2bth.h, bt_sdp.h, bthapi.h, bt_api.h, winioctl.h, windows.h
This is the code:
int Main(int argc, char **argv)
{
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd)){
wprintf(L"Initialization of socket subsystem failed! Error = %d\n", WSAGetLastError());
return 0;
}
SOCKET server = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if(server == INVALID_SOCKET){
printf("socket failed, error %d\n", WSAGetLastError());
return 0;
}
return 0;
}
This compiles, but when running it fails at the socket creation. GetLastError returns 10043, which means WSAEPROTONOSUPPORT. A quick search gives me this list with error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
I have no idea what I'm doing wrong. The code runs on a normal laptop with bluetooth, so I suspect it has something to do with the driver or so.
Any help is appreciated!
Kind Regards

Related

Winsock program causing port exhaustion

Going off a different post that helped explain the source of the symptoms of my issue: https://superuser.com/questions/1348102/windows-10-ephemeral-port-exhaustion-but-netstat-says-otherwise
I am having a very similar issue - except the problem is the program eating up all the ports is one I created myself.
See the top 2 results
See the top 2 results - 6072 ports used by one instance and 545 by the other - if I understand that result set correctly.
There are 2 instances listed as there are 2 instances running - this is a program that connects to a machine every 60 seconds, asks if it has information, retrieves it if it does, and then closes the connection.
It was written in C++ using winsock TCP connections.
Is there anything someone could suggest I modify to prevent this from happening?
Currently, after about a month and a half of the program running, we run into the issue of not being able to RDC into the server "due to a time and date difference" even though the time and date are perfectly in sync with the NTP server and the rest of the computers, and of course it will seize being able to connect to anything.
We can still connect to the server directly through IP address, but not hostname.
I haven't yet found any solutions to this other than rebooting the server.
The mechanism for connecting is a simple and primitive:
void Connect(string ipA)
{
// Initialize Winsock
Debug("Connecting to socket...");
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
Debug("Client: Error at WSAStartup().");
}
else
{
Debug("Client: WSAStartup() is OK.");
}
// Create a SOCKET for connecting to server
u_long mode = (u_long)0;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
GPT_ATTRIBUTE_NO_BLOCK_IO_PROTOCOL;
if (ConnectSocket == INVALID_SOCKET)
{
printf("Client: Error at socket(): %ld.\n", WSAGetLastError());
WSACleanup();
return;
}
iResult = ioctlsocket(ConnectSocket, FIONBIO, &mode);
if (iResult != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", iResult);
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(ipA.c_str());
clientService.sin_port = htons(port);
// Connect to server.
if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
Debug("Connection failed...");
WSACleanup();
return;
}
else
Debug("Connection successful.");
}
This method is called with the IP address supplied as a parameter and results in a successful connection.
After that, several request-response packets are sent using these:
void SendPacket(int iResult, SOCKET ConnectSocket, const char* a)
{
Debug("Sending message to CW: " + (string)a);
iResult = send(ConnectSocket, a, strlen(a), 0);
if (iResult == SOCKET_ERROR) {
Debug("Send failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Send successful.");
}
And
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
And once we're done with the particular session, we close the connection:
void ShutDown(int iResult, SOCKET ConnectSocket)
{
iResult = shutdown(ConnectSocket, SD_SEND);
Debug("Shutting down socket...");
if (iResult == SOCKET_ERROR) {
Debug("Shutdown failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Shutdown successful.");
}
There are a couple hundred lines of code that handles the data received, but those won't be relevant as they don't deal with any sort of network connection.
To say I have no experience with C++ would be an understatement, I simply slapped this together using basic MS templates until it worked exactly as we needed it and haven't touched it since.
So if there is anything someone can point out that I could change to avoid port exhaustion, I would be very grateful.
Just to add a bit of clarity - the program will ALWAYS connect to the machine on the same port. I have tried to bind the outgoing connection (from Windows) port to the same one also, but I have been unsuccessful - wasted many hours trying to get this 1 simple thing right, but I presume that would resolve my issues.
I see that you are calling shutdown when you are done with a connection and if we consult the documentation for that we see:
The shutdown function does not close the socket. Any resources attached to the socket will not be freed until closesocket is invoked.
Which I take to mean that any ports associated with the socket remain in use.
Further down that page, we also read:
An application should not rely on being able to reuse a socket after it has been shut down. In particular, a Windows Sockets provider is not required to support the use of connect on a socket that has been shut down.
So, all-in-all, I would call closesocket instead of shutdown and then request a new socket from Winsock when you need one.

Can a Bluetooth device be detected by its unique address from Windows C++ application?

I have to write an application which has to identify "ESP32" devices & send/receive data from a Windows C++ application.
Q1: I am using WSALookupServiceBegin() API to find the BT device, it was not working as expected. API returns 10108 until I manually click on "Add devices" in Windows Bluetooth window. Is there any other API/service which can discover BT near devices or am I using the WSALookupServiceBegin() API wrongly?
Is WSALookupServiceBegin() takes the device data from the Bluetooth cache? I got this doubt because API works fine only after manual search in Windows.
Q2: is it possible to connect to any Bluetooth device just with the Mac ID of BT device from Windows?
Please find the code below.
WSAQUERYSET data;
HANDLE handle;
ZeroMemory(&data, sizeof(data));
data.dwSize = sizeof(data);
data.dwNameSpace = NS_BTH;
data.lpcsaBuffer = NULL;
WSALookupServiceBegin(&data, LUP_CONTAINERS, &handle);
while(WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR,
&dwSize, pwsaResults)
{
service_classID = pwsaResults->lpServiceClassId;
_BTH_DEVICE_INFO *dev = (_BTH_DEVICE_INFO *)pwsaResults->lpBlob->pBlobData;
SOCKET LocalSocket = INVALID_SOCKET;
SOCKADDR_BTH SockAddrBthServer;
SockAddrBthServer.btAddr = dev->address;
SockAddrBthServer.addressFamily = AF_BTH;
SockAddrBthServer.serviceClassId = *service_classID;
SockAddrBthServer.port = 0;
// connect to socket
LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if (INVALID_SOCKET == LocalSocket) {
wprintf(L"socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError());
return -1;
}
if (SOCKET_ERROR == connect(LocalSocket,
(struct sockaddr *) &SockAddrBthServer,
sizeof(SOCKADDR_BTH))) {
wprintf(L"connect() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
return -1;
}
}
OUTPUT :
connect() call failed. WSAGetLastError=[10049]
WSALookupServiceBegin is correct way but you have to provide correct flags for it. Also you can use BluetoothFidnFirstDevice and BluetoothFindNextDevice functions from Bluetooth API.
However both methods always return paired devices even they are not available (together with just found devices).
From your description it looks you did not provide correct flags for WSAxxx function.
If you know device's MAC and it has not been changed then you can connect to device by MAC without rediscovering it each time. Depending on your device's authentication requirement you even do not need to pair with device (of course if your device does not need authentication and/or encryption).

Sendto function return error - UDP socket on windows

I have problem with sendto function. I want to get time from UDP server. My code like this:
unsigned char msg[48]={010,0,0,0,0,0,0,0,0};
char* hostname=(char *)"tick.usno.navy.mil";
sockaddr_in server_addr;
WSAData data;
int result=WSAStartup( MAKEWORD( 2, 2 ), &data );
if (result != NO_ERROR) {
printf("WSAStartup failed with error: %d\n", result);
return 1;
}
int client_s = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
if (client_s == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
unsigned short Port = 123;
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(Port); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
char out_buf[BUFFER_SIZE];
int retcode = sendto(client_s, reinterpret_cast<const char*>(msg), sizeof(msg), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
perror("sendto:");
if (retcode == SOCKET_ERROR) {
printf("sendto failed with error: %d\n", WSAGetLastError());
closesocket(client_s);
WSACleanup();
return 1;
}
My output is like:
sendto:: No error
sendto failed with error: 10013
When I try recive data with recv, I got something wrong. I want get time from UDP server on windows with c++. Where is problem here? Why one error say no error and one error 10013 and how can I fix that?
The old answer (kept below) is informational but not correct for this case.
The problem is most likely these two lines
char* hostname=(char *)"tick.usno.navy.mil";
...
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
The inet_addr function expects a dotted-decimal IPv4 address. Not an unresolved host-name. If not a valid IPv4 dotted-decimal address is provided, the function will return INADDR_NONE which is not a valid address and will lead to problems when using the address in e.g. sendto. Will it cause the error reported in the question? I honestly don't know, but it will definitely not work as expected.
To resolve a host-name into an IP address you should use getaddrinfo. The linked reference also contains an example on how to use it.
The error 10013 is, if you look at e.g. this Windows socket error reference WSAEACCESS, that there is some permission problems. If you then search a little you will see that ports under 1024 are reserved for the system, and you need elevated privileges to use them.
If you want to create an NTP server or client you need to run your program using elevated access rights, like e.g. using "Run as administrator".
As for the message
sendto:: No error
it comes from the perror call you unconditionally call after sendto. First of all on Windows the socket functions doesn't set errno which perror uses. Secondly, the state of errno is undefined if the previous call to didn't actually fail.
So don't use it unconditionally, and don't use it for the Windows socket functions.

Client connects to server but server does not think client has connected in C++

I have a C++ program, using mpi, that follows a typical client server model. Each mpi instance of the client connects to a corresponding mpi instance of the server. This has worked relatively well until I have had to do some testing with added latency (1 second of added latency to be precise).
Problem:
Sometimes one of the server processes do not think the client has connected but the client thinks it has connected. i.e. After using gdb, the server is waiting at accept() but the client has continued on past connect(). Thus, it appears the client thinks it has connected when the server does not think it has connected.
My best guess is that I need to set an sock-option somewhere, however talking to fellow programmers and googling has not yielded any helpful results.
EDIT:
There are two sets of MPI processes (so two different calls to mpirun), the accept() and connect() calls are for the sockets, which are between the two sets of MPI processes. It is openmpi.
The code (from someone else's code, actually) [reduced]:
Client (connect code): (m_socket is the actual socket)
if (-1 == m_socket)
{
perror("cannot create socket");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
res = inet_pton(AF_INET, host_ip, &addr.sin_addr);
if (0 > res)
{
perror("error: first parameter is not a valid address family");
close(m_socket);
exit(EXIT_FAILURE);
}
else if (0 == res)
{
perror("error: second parameter does not contain valid IP address");
close(m_socket);
exit(EXIT_FAILURE);
}
//backoff
for (int sec = 1; sec < 20000; sec++ )
{
int ret;
if (0 == (ret = connect(m_socket, (struct sockaddr *)&addr, sizeof(addr))))
{
return;
}
sleep(1);
close(m_socket);
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}
perror("connect failed");
close(m_socket);
exit(EXIT_FAILURE);
Server: (m_socket is the actual socket)
int socket = ::accept(m_socket, NULL, NULL);
if(socket < 0)
{
fprintf(stderr, "accept() failed: %s\n", strerror(errno));
close(m_socket);
exit(EXIT_FAILURE);
}
It looks like you're trying to do your connect/accept manually rather than with MPI. You might take a look at the example on Deino (http://mpi.deino.net/mpi_functions/MPI_Comm_accept.html) if you're trying to use MPI for your connections.
Alternatively, you might just need to look at a more general tutorial (some available here: http://www.mcs.anl.gov/research/projects/mpi/tutorial/) of MPI to get a feel for how communication works. Most of the time and application doesn't use Connect/Accept to communicate, but uses MPI Communicators to set up communication mechanisms between processes. It's a different model (SPMD as opposed to MPMD).

Linux UDP Server unreachable from Window 7

I have the following configuration for my experiment.
Wifi(Belkin) router connected to Internet.
Laptop with Windows 7 OS
Laptop with Ubuntu OS.
Experiment: When I connect both of my laptop to Wifi router it assigns DHCP IPs 192.168.2.2 to Linux & 192.168.2.3 to Win 7. Both of them can browse internet.
I start a UDP server on my Linux machine with the following code.
int main(int argc, char *argv[]) {
int sd, rc, n, cliLen, flags;
struct sockaddr_in cliAddr, servAddr;
char msg[MAX_MSG];
//Create a socket
sd=socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0){ printf("%s: cannot open socket \n",argv[0]); exit(1); }
//Bind now to a port
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.2.2");
servAddr.sin_port = htons(9999);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0) {printf("%s: cannot bind port number %d \n", argv[0], 9999);exit(1);}
//We are done ... Notify User
printf("%s: waiting for data on port UDP %u\n",argv[0],LOCAL_SERVER_PORT);
//Server's Infinite Loop
while(1)
{
memset(msg,0x0,MAX_MSG);//Sanity
/* receive message */
cliLen = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, flags,(struct sockaddr *) &cliAddr, (socklen_t * )&cliLen);
if(n<0){printf("%s: cannot receive data \n",argv[0]);continue;}
//Received message
printf("%s: from %s:UDP%u : %s \n", argv[0],inet_ntoa(cliAddr.sin_addr),ntohs(cliAddr.sin_port),msg);
sleep(1);
//Sending back the data thus received
sendto(sd,msg,n,flags,(struct sockaddr *)&cliAddr,cliLen);
}//while
return 0;
}
This code work well & I can receive the packet to the server when some local client on the Linux machine tries to contact my server.
PROBLEM : When I make the same client in Android AVD present in my windows 7 system I am unable to reach my server.
I thought may be that's firewall issue, so I removed the firewall & added by pass custom rules to the IP "192.168.2.2" as given in the following link. http://www.brighthub.com/computing/windows-platform/articles/40014.aspx#
But it did not work. I thought that first I should try with raw java first then with AVD.
Hence, I created a UDP client with Java code still I was not able to connect to server.
Then I thought let's try with raw C++ so that I would come to know exactly what is the problem. Following is the Visual Studio code which I implemented for the same.
#define PORT_NUM 9999 // Port number used
#define IP_ADDR "192.168.2.2" // IP address of server1
#define BUFFER_SIZE 4096
void main(void){
WORD wVersionRequested = MAKEWORD(2,2); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
int client_s; // Client socket descriptor
struct sockaddr_in server_addr; // Server Internet address
int addr_len; // Internet address length
char out_buf[BUFFER_SIZE]; // Output buffer for data
char in_buf[BUFFER_SIZE]; // Input buffer for data
int retcode; // Return code
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
client_s = socket(AF_INET, SOCK_DGRAM, 0);
if (client_s < 0){ printf("*** ERROR - socket() failed \n"); exit(-1);}
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
strcpy(out_buf, "Test message from CLIENT to SERVER");
retcode = sendto(client_s, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
if (retcode < 0){printf("*** ERROR - sendto() failed \n");exit(-1);}
addr_len = sizeof(server_addr);
retcode = recvfrom(client_s, in_buf, sizeof(in_buf), 0,(struct sockaddr *)&server_addr, &addr_len);
if (retcode < 0){printf("*** ERROR - recvfrom() failed \n");exit(-1);}
printf("Received from server: %s \n", in_buf);
retcode = closesocket(client_s);
if (retcode < 0){ printf("*** ERROR - closesocket() failed \n");exit(-1);}
WSACleanup();
}
But it gives me error of destination unreachable.
To find out exactly what is going on at the packet level, I installed "Wireshark", on my ubuntu machine.
My observation is... whenever my windows client executes I get a ICMP message 3 times on the Wireshark having the type 3 message. The detailed analysis of the packet showed that the port is unreachable.
Kindly help me to find out what I am missing here :(.
Have you tried disabling the firewall on the linux machine, or adding an exception for the port you are using?
sudo ufw disable
or use the following to show your iptables firewall rules:
sudo iptables -L
Check the connection between the two machines
ICMP: ping win->lin and back
TCP: connect SSH, Samba, or even browser if you can run some web server
UDP: use nc (netcat) utility to test UDP/TCP connection between two machines
If one of these does not work, look for the problem :
Shut down the firewalls on both computers and on the wireless AP, run sniffers on Win and on Lin machines.
If the connection is ok, the you know you have a bug in your program. Start debugging each end against something working - i.e. nc.