I need some help with the windows socket programming. I want to make a communication between an android phone (client) and a c++ application (server) with TCP over Bluetooth. On server-side I use windows sockets.
I already established a connection between both instances via RFCOMM but I want to make it over TCP/ IP. Does anyone know how I can create a Bluetooth socket under windows and send TCP messages over it?
Thanks a lot!
%*********** Update *************%
Recently, I tried to implement it via the windows stack. The connection is established but die communication is still rfcomm based. Does anyone know where my error or false thinking is?
serverSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
// error checks
SOCKADDR_BTH sa;
memset (&sa, 0, sizeof(sa));
sa.addressFamily = AF_BTH;
sa.port = 11 & 0xff;
sa.serviceClassId = TCP_PROTOCOL_UUID;
bind(serverSocket, (SOCKADDR*)&sa, sizeof(sa) );
// error checks
// Register Service
WSAQUERYSET service1;
memset(&service1, 0, sizeof(service1));
service1.dwSize = sizeof(service1);
service1.lpszServiceInstanceName = _T("ViL Data...");
service1.lpszComment = _T("Pushing data to Android");
GUID serviceID1 = TCP_PROTOCOL_UUID;
service1.lpServiceClassId = &serviceID1;
service1.dwNumberOfCsAddrs = 1;
service1.dwNameSpace = NS_BTH;
CSADDR_INFO csAddr1;
memset(&csAddr1, 0, sizeof(csAddr1));
csAddr1.LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
csAddr1.LocalAddr.lpSockaddr = (sockaddr*)&sa;
csAddr1.iSocketType = SOCK_STREAM;
csAddr1.iProtocol = IPPROTO_TCP;
service1.lpcsaBuffer = &csAddr1;
WSASetService(&service1, RNRSERVICE_REGISTER, 0)
// error checkings
This works all fine and I can connect to the server from my Android app. But I'm still confused why it doesn't transmit it over TCP. Can anyone help?
RFCOMM is an emulated serial port, it has nothing to do with Internet Protocols directly. You'd need to create a transport that runs over RFCOMM, e.g. a PPP connection. On Windows you'd do it by adding a new connection using the network settings from the control panel. The PPP would run over a null modem, essentially. Your application could do it programmatically, to, but it's a whole series of steps. Or, if you don't want to mess with Windows networking stack settings, you could embed a networking stack into your application and have it speak directly using PPP via the RFCOMM port.
Related
I have a Xamarin application that requires to connect to a device from the LAN side and also the WAN side. The device (an ESP8266) is connected via WiFi to an internal network and can be accessed from the WAN side via DDNS.
When the user makes a request (via the Xamarin app), whilst using mobile data (i.e. they are not connected to the WiFi network), the request reaches the IoT device (the IoT device makes a UPNP mapping on the router).
The IoT device uses mDNS to make itself known on the local network, and if I try to connect via Chrome on Windows 10 on a machine connected to the same network, the connection is successful (using 'domain.local'). Doing the same on on Chrome on Android gets a DNS error.
If the user now connects the phone to the same network as the IoT device, the Xamarin app request will no longer reach the IoT device. I have some code which distinguishes between a local request and a remote request which makes either a 'domain.local' request or a 'domain.ddns.net' request.
I understand the Apple Bonjour aspect of this on my desktop machine and the lack thereof on the Android platform.
Does anyone know how to resolve this?
So I have solved this and have posted the answer in case it's useful to someone in future.
Using the library Zeroconf https://github.com/novotnyllc/Zeroconf in Xamarin
private const string deviceHostName = "yourhostname"
public static async void GetDeviceIPAddress()
{
IReadOnlyList<IZeroconfHost> responses = null;
responses = await ZeroconfResolver.ResolveAsync("_http._tcp.local.");
foreach (var resp in responses)
{
if (resp.DisplayName == deviceHostName)
{
Debug.Print(resp.IPAddress);
}
}
}
Now making a http request to resp.IPAddress reaches the device advertising it's hostname as 'yourhostname'.
I am using an ESP8266 and it was important to start MDNS on the device BEFORE connecting the WiFi otherwise the device reports it's hostname as ESP_xxxx rather that 'yourhostname' which was the real root of the problem.
I'm trying to detect a network connected device using multicast from a Ruby program. I've sniffed the network traffic from the official detection program and found that the computer sends out a packet to 225.0.0.37:12345 and the device responds on 225.0.0.38:12346. The device is connected to a local network consisting of a Netgear switch, a Windows computer and a Linux computer. I've made my program to send out an identical packet as the official program does.
The problem I have is that the response is never received, neither by my program nor the official detection program. Using Wireshark I can clearly see the device responding without fail and the packet clearly makes it to my Linux computer which I run Wireshark on, but neither the official program running on the Windows computer, nor my own Ruby program running on the Linux computer gets the response.
Both my computers have two network adapters, one connected to the same local switch and one connected to another switch which is then connected up to a large LAN with internet access. I've tried using a different brand switch between the computers, but it made no difference.
I've searched far and wide on Internet and haven't found anything to solve my issue. I appreciate any help I can get.
Here are the relevant packets captured with tcpdump, the first is sent from my program and the second is the response from the device:
13:30:25.773019 IP 192.168.0.1.12345 > 225.0.0.37.12345: UDP, length 15
13:30:25.773770 IP 192.168.0.125.39129 > 225.0.0.38.12346: UDP, length 228
Here is a (simplified) snippet from my program:
MULTICAST_SEND_ADDRESS = '225.0.0.37'
MULTICAST_SEND_PORT = 12345
MULTICAST_RESPONSE_ADDRESS = '225.0.0.38'
MULTICAST_RESPONSE_PORT = 12346
BIND_ADDRESS = '0.0.0.0'
# Transmit packet on all adapters - this part works fine
packet = [ID_STRING].pack("Z*")
addresses = Socket.ip_address_list
addresses.each do |addr|
next unless addr.pfamily == Socket::PF_INET
socket = UDPSocket.new
socket.bind(addr.ip_address, MULTICAST_SEND_PORT)
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send(packet, 0, MULTICAST_SEND_ADDRESS, MULTICAST_SEND_PORT)
socket.close
end
# Receive packet - this should work, but doesn't
membership = IPAddr.new(MULTICAST_SEND_ADDRESS).hton + IPAddr.new(BIND_ADDRESS).hton
listen_socket = UDPSocket.new
listen_socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, membership)
listen_socket.bind(BIND_ADDRESS, MULTICAST_RESPONSE_PORT)
packet, addr = listen_socket.recvfrom(1024)
# We never get to this line since there's nothing received
puts packet
I figured out the problem in the end. In spite of what all the code examples I've seen say, it seems you can't bind to address '0.0.0.0' to get all interfaces on a multihomed machine. I don't know if this used to work and has been changed or all examples I've found have only been tested on singlehomed machines, but when I bound the socket to the actual ip of the correct interface it started working.
Im trying to open a L2Cap HID Channel And Interrupt channel so I can send HID commands to a bluetooth device.
I've done all my service advertising and device paring and established a baseband connection.
The Hid Control channel opens fine.
When I try to create my kBluetoothL2CAPPSMHIDInterrupt connection
l2capChannelQueueSpaceAvailable
delegate method called (not sure what this means) followed by
l2capChannelOpenComplete
but the connection closes immediately calling
l2capChannelClosed
How can I correctly open these connection?
I've spent a long time digging through the IOBlueTooth framework and the bluetooth.org HID spec but theres barely any helpful information (that I can find at least).
When i trace out my L2Cap channels I see some null values for
mIncomingDataListener
and
mEventDataListener
. I dont know how to set these or if they have anything to do with my problem.... just speculating.
The code snippet below is my attempt so far to make the connections after a connection to the device has been established.
-(void)establishL2CappConnections:(IOBluetoothDevice*)device
{
IOReturn r;
IOBluetoothL2CAPChannel *ch1;
r = [device openL2CAPChannelSync:&ch1
withPSM:(BluetoothL2CAPPSM)kBluetoothL2CAPPSMHIDControl
delegate:self];
self.mL2CappChannel=ch1;
NSLog(#"r == %i",r);
IOBluetoothL2CAPChannel *ch2;
r = [device openL2CAPChannelSync:&ch2
withPSM:(BluetoothL2CAPPSM)kBluetoothL2CAPPSMHIDInterrupt
delegate:self];
self.mL2CappInterruptChannel=ch2;
NSLog(#"r == %i",r);
}
Edit:1
I've attached my packet logs. It's strange, a request for
kBluetoothL2CAPPSMSDP 0x0001
gets made without me requesting it and then everything starts disconnecting.
BT Packet Logs
As per your logs its very clear that your device in in Limited Connection mode, its stays Active for 30sec or less. change device settings to make it General Discoverable.
kBluetoothL2CAPPSMSDP 0x0001
means Bit 13 - Limited Discoverable Mode
Playing with the Bluetooth settings will solve your problem
I am using the 32feet bluetooth library to connect to a device that supports Serial Port Profile (SPP). I try to connect like this:
using (BluetoothClient client = new BluetoothClient())
{
var address = new BluetoothAddress(0xecfe7e11c3af);
BluetoothEndPoint endPoint = new BluetoothEndPoint(address, BluetoothService.SerialPort);
client.Connect(endPoint);
var stream = client.GetStream();
System.Threading.Thread.Sleep(10000);
}
Everything is great until the Connect method is called. At this point, Windows interrupts the program flow with a bubble alert that says
"A bluetooth device is trying to connect -- click to allow this"
At which point the user is led through a wizard that ends up installing drivers and a Bluetooth virtual COM port shows up in Device Manager. I don't want this to happen -- I want to simply access the stream and communicate directly with the device without windows intervening. Is this possible? What can be done to tell Windows to keep out of my business?
I'm attempting to connect to a Bluetooth 4.0 device. I've done something similar in the past with a 2.0 device and Windows does not interfere in this case.
Have a look at http://SimpleBluetooth4Win.SourceForge.net
It's a small wrapper library that uses the windows bluetooth networking API that could help you.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa362932%28v=vs.85%29.aspx
In particular if your bluetooth USB dongle or bluetooth device has been correctly recognized by the appropriate drivers and the remote bluetooth device is already paired with the PC, you don't need to install a bluetooth virtual COM port that shows up in Device Manager but you simply use the write or read calls to access directly the stream for communicating with the paired device.
I am testing an application which communicates to a server via a UDP port, and I need to block this port to make sure the application can handle it.
The Problems:
1. It has to be done in an automated test (which is controlled by VBScripts).
2. It has to be done in Windows XP, without using a firewall.
I have tried this:
Set objFirewall = CreateObject("HNetCfg.FwMgr")
Set objPolicy = objFirewall.LocalPolicy.CurrentProfile
Set colPorts = objPolicy.GloballyOpenPorts
Set objPort = colPorts.Item(9999,6)
objPort.Enabled = FALSE
but it did not work.
This may be of interest:
How to block specific network protocols and ports by using IPSec
http://support.microsoft.com/kb/813878