I have an interesting problem that appears to be related to multicast being switched off (at the kernal) on newer andriod devices, please note This is NOT an issue with setting up UDP on multi adapters or LTE/WIFI, I understand that.
A lot of googling and trying loads things out have offered up a multitude of answers, e.g. acquire multi cast locks and some git hub issues where people say its impossible as devices have multicast disabled in the kernel. I have also just found this on SO
My code works fine on:-
Nexus 5 Andriod 8.1 - API 27
Lenovo Tablet Andriod 8.1 - API 27
That is it can send and receive UDP packets that is not directly targeted to the IP address of the phone.
It does NOT receive UDP packets on:-
Pixel 3a Andriod 10/11 APIS 29/30
The Xamarin forms code to replicate this is:
public TestCameraPage()
{
InitializeComponent();
sendClient = new UdpClient
{
EnableBroadcast = true,
ExclusiveAddressUse = false,
MulticastLoopback = true
};
sendClient.Client.Bind(new IPEndPoint(IPAddress.Any, CameraPort));
Lab1.Text = "Started to listen for UDP packets";
sendClient.BeginReceive(DiscoverCallback, sendClient);
}
private void DiscoverCallback(IAsyncResult result)
{
try
{
var ep = new IPEndPoint(IPAddress.Any, CameraPort);
var data = sendClient.EndReceive(result, ref ep);
var msg = $"Received: {Encoding.UTF8.GetString(data)}";
//Sniff out camera IP
var ip = $"{data[15]}.{data[14]}.{data[13]}.{data[12]}";
Device.BeginInvokeOnMainThread(() =>
{
Lab1.Text = $"CAMERA IP: {ip} FULL MESSAGE: {msg}";
});
}
finally
{
sendClient.BeginReceive(DiscoverCallback, sendClient);
}
}
private void Button_OnClicked(object sender, EventArgs e)
{
var data = PollMessageToCamera();
sendClient.Send(data, data.Length, "255.255.255.255", ListeningPort);
}
So my questions are two fold
Is it possible to receive UDP packets that are NOT broadcasted directly to the device on a newer Andriod phone?
If it is possible what do I need to do to fix it?
Example output on nexus and tablets
I should also point out I have a console app that can send UDP messages and if I use this (ip address of pixel 3a), it works
sendClient.Send(data, data.Length, "192.168.1.248", CameraPort);
If I use 255.255.255.255 (multi cast) in console app only the nexus and tablet works the pixel 3a doesn't
sendClient.Send(data, data.Length, "255.255.255.255", CameraPort);
Related
I've been trying to connect to a specific wifi through code, but with no succcess.
This is what i've come up with:
public void ConnectToWifi(string ssid, string password)
{
WifiManager wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService);
if (!wifiManager.IsWifiEnabled)
{
wifiManager.SetWifiEnabled(true);
}
string formattedSsid = $"\"{ssid}\"";
string formattedPassword = $"\"{password}\"";
WifiConfiguration wifiConfig = new WifiConfiguration
{
Ssid = formattedSsid,
PreSharedKey = formattedPassword
};
var addNetwork = wifiManager.AddNetwork(wifiConfig);
WifiConfiguration network = wifiManager.ConfiguredNetworks.FirstOrDefault(n => n.Ssid == ssid);
if (network == null)
{
Console.WriteLine($"Cannot connect to network: {ssid}");
return;
}
wifiManager.Disconnect();
bool enableNetwork = wifiManager.EnableNetwork(network.NetworkId, true);
}
I've added permissions.
When testing it does turn the wifi on atleast, so i know it works until that point. What seems not to be working is the AddNetwork part.
I appreciate any help i can get!
You are missing one key method - reconnect(). You can read more about it in the WifiManager's docs here
The important part of the documentation is:
Reconnect to the currently active access point, if we are currently disconnected.
So, what you need to do it after you have disconnected and enabled your new network, call in the end this and you will be good to go:
wifiManager.Disconnect();
wifiManager.EnableNetwork(network.NetworkId, true);
wifiManager.Reconnect(); // This is the missing method
NB: Keep in mind that most of the WifiManager's code that you are using is being obsolete starting Android 10. So, if you want to target Android 10, then you will need to write an additional code for the connectivity for devices with Android 10+.
I had some code that uses PNRP to discover peers on network. Everything works fine since Windows 10 update 1803.
public void Init()
{
try
{
_ServiceUrl = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => address.AddressFamily == AddressFamily.InterNetwork).Select(address => _Address = address).Select(address => $"net.tcp://{address}:{Port}/SiemensVR").FirstOrDefault();
if (string.IsNullOrEmpty(_ServiceUrl)) return;
_LocalProxy = new PeerProxy(_EventAggregator, this);
_Host = new ServiceHost(_LocalProxy, new Uri(_ServiceUrl));
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
_Host.AddServiceEndpoint(typeof(IPeerContract), binding, new Uri(_ServiceUrl));
_Host.Open();
_PeerName = new PeerName(PEER_NAME_ID, PeerNameType.Unsecured);
_PeerNameRegistration = new PeerNameRegistration(_PeerName, Port) { Cloud = Cloud.AllLinkLocal };
_PeerNameRegistration.Comment = _UserId.ToString();
_PeerNameRegistration.Start();
ResolvePeers();
}
finally { }
}
private async void ResolvePeers()
{
var resolver = new PeerNameResolver();
resolver.ResolveProgressChanged += OnResolveProgressChanged;
resolver.ResolveCompleted += (s, e) =>
{
Console.WriteLine("Completed");
};
resolver.ResolveAsync(_PeerName, this);
await Task.Delay(1000);
resolver.ResolveAsyncCancel(this);
}
Does MS have replace PNRP by something ?
I already tested to activate pnrp services, reinstall teredo tunneling and more.
Microsoft has deprecated and is in the process of removing PNRP.
You're out of luck, since its service and client APIs are being removed completely.
See https://learn.microsoft.com/en-us/windows/deployment/planning/windows-10-deprecated-features
Having the same issue here... Let me know if you find any resolution.
Previously, our application works fine, but on 1803 it doesn't work anymore. I can see the cloud start to synchronize and then each peer just ends up going to status alone.
Same issue, I found a Microsoft note to set the following services to Automatic Delayed Start:
Computer Browser (Browser) <- Set to Automatic, not delayed start
Function Discovery Provider Host (FDPHost)
Function Discovery Resource Publication (FDResPub)
Network Connections (NetMan)
UPnP Device Host (UPnPHost)
Peer Name Resolution Protocol (PNRPSvc)
Peer Networking Grouping (P2PSvc)
Peer Networking Identity Manager (P2PIMSvc)
But it didn't resolve the issue.
Any progress in resolving this?
I have Windows 10 Pro, build 10586.494 on HP ZBook G2. When I go to Settings -> Devices -> Bluetooth and switch on Bluetooth, I can see nearby BLE devices (they are custom made BLE devices manufactured by my company).
I want to interact with my BLE devices in Universal Windows application (in Visual Studio 2015). I use this code (it is just a snippet of code)
BluetoothLEAdvertisementWatcher watcher;
//....
watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active };
watcher.Received += WatcherOnReceived;
watcher.Start();
//....
private void WatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs btAdv)
{
}
When I run this application, WatcherOnReceived is never executed (although watcher.Start was executed). Why and how to fix it?
If found a better workaround for this. (I'm using Win 10 1803.)
First, to recap the problem since the original question is not entirely clear about it:
BluetoothLEAdvertisementWatcher works if BLE device is advertising before watcher.Start()
BluetoothLEAdvertisementWatcher does not work if BLE device starts advertising after watcher.Start()
If BluetoothLEAdvertisementWatcher is not working after watcher.Start(), it will begin working when Windows 10 Bluetooth Settings is opened or closed (i.e. the opening or closing of the settings window triggers BluetoothLEAdvertisementWatcher to start working)
So, the workaround I came up with is to keep starting and stopping a second BluetoothLEAdvertisementWatcher in the background to create the same sort of trigger that the Windows Bluetooth Settings window provides.
For example, using a WinForms timer:
...
var timer = new Timer { Interval = 1000 };
timer.Tick += Timer_Tick;
timer.Start();
...
private void Timer_Tick(object sender, EventArgs e)
{
var watcher = new BluetoothLEAdvertisementWatcher();
watcher.Received += (s, a) => { };
watcher.Start();
Task.Delay(500).ContinueWith(_ => watcher.Stop());
}
I have to keep Bluetooth switched on in Settings -> Devices -> Bluetooth in order to receive advertisements in my app.
and thanks for taking the time to read this.
Concept
Connect a wiimote to a windows (or mac) using the default HID driver and service (because BT L2CAP is not yet supported in chrome.bluetoothSocket). I wan't to send and receive data from the device; buttons, gyroscope, IR camera, etc ... .
My setup (relevant parts)
Macbook pro (installed Yosemite)
Chrome Canary (Version 41.0.2246.0 canary (64-bit)), running in verbose logging mode
Windows 7 through bootcamp
Wiimote (Nintendo RVL-CNT-01)
Code to send data to device
var _wiimote = this;
var bytes = new Uint8Array(21);
var reportId = 0x11;
bytes[0] = 0x10;
chrome.hid.send(_wiimote.connectionId, reportId, bytes.buffer, function() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
console.log(chrome.runtime.lastError);
}
console.log("Wiimote send data");
chrome.hid.receive(_wiimote.connectionId, function(reportId, data) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
console.log(chrome.runtime.lastError);
return;
}
console.log("done receiving.");
console.log("received:" + data.byteLength);
});
});
Expected behavior?
Light up the first LED and stop the blinking that starts when connection, but not pairing, the device.
Actual behavior?
The console shows "Wiimote send data" but the LEDs do not react on the sent report.
So this code doesn't do much, but according to the documentation on wiibrew(see resources below).
It should send to the wiimote to light up the first LED. This goes for any output report I'm sending to the device. It does react when I use wrong reportIds or different byte lengths, then it fails.
Next up would be the receiving part, if I were to send anything (really any data) to reportId 0x15 on the wiimote, it should send me an information report. I've tried polling for messages like this:
Code to receive data from the device
var _wiimote = this;
var pollForInput = function() {
chrome.hid.receive(_wiimote.connectionId, function(reportId, data) {
console.log("receiving something",reportId);
if (_wiimote.pollReceive) {
setTimeout(pollForInput, 0);
}
});
};
Expected behavior?
After sending 0x00 to the reportId 0x15 I should receive an information report from the wiimote device.
Actual behavior?
I've never received anything in the console output indicating communication from the device.
Resources used
http://wiibrew.org/wiki/Wiimote
https://developer.chrome.com/apps/hid
I am building a windows phone 7.1 app. I need to find out if the phone is connected to any Wifi and if so, what is its current IP in the local network (ie. 192.168.0.100 like this).
I've been trying to find out these information for some time now. Please help.
I've managed to get the local IP on my console app by using the following code
public void ScanIP()
{
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
String localIP = ip.ToString();
Console.WriteLine(localIP);
}
}
Console.ReadKey();
}
However, I need similar thing done for windows mobile 7 app. Any idea ? Please share.
Do a multicast and listen for replies. Once you identify your multicast message, you can get the IP of the sender (which is yourself). You can use UdpAnySourceMulticastClient to do the multicasting. In case you're not in a wifi network, you will get a socket failure in the EndJoinGroup call. You should handle the exception and pass a specific value indicating you're not in a wifi network.
More info in this blog post by Andy Pennell.
it will provide you the ip address of the phone ...
public static IPAddress Find()
{
List<string> ipAddresses = new List<string>();
var hostnames = NetworkInformation.GetHostNames();
foreach (var hn in hostnames)
{
if (hn.IPInformation != null)
{
string ipAddress = hn.DisplayName;
ipAddresses.Add(ipAddress);
}
}
IPAddress address = IPAddress.Parse(ipAddresses[0]);
return address;
}