Sending data via Bluetooth using StreamSocket - c#

I wanted to transmit an array over Bluetooth using Windows Phone 8, so I referred to the following intro guide on MSDN: http://msdn.microsoft.com/en-us/library/windows/apps/jj207007(v=vs.105).aspx
Pairing/Connecting was pretty straightforward and when I deployed the app to my Lumia 620 I was able to see my paired HTC Desire using the sample code in the above. So next I tried sending a basic 5-byte array using the following code:
async void BLEfunc()
{
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var peers = await PeerFinder.FindAllPeersAsync();
if (peers.Count == 0)
{
Details.Text = "No Device Found";
}
else
{
PeerInformation selectedPeers = peers[0];
StreamSocket socket = new StreamSocket();
await socket.ConnectAsync(selectedPeers.HostName, "1");
Details.Text = "Connected to device: " + selectedPeers.DisplayName; //Details is a TextBlock on screen
using (var dataWriter = new DataWriter(socket.OutputStream))
{
//byte[] DataArray = { 1, 2, 3, 4, 5 };
dataWriter.WriteByte(1);
var result = await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
Details.Text = "Data sent!";
}
}
The problem is that the program runs into an unhandled exception when it enters the using code block in the above pasted code. Everything up to that point runs fine. I got the idea for the above code from here: Sending files via bluetooth from winRT to android / WP devices
Any ideas?

Related

How can I connect to a Bluetooth service on Gear S3?

I am writing a web app for the Gear S3 and a companion Win-App for UWP in C#.
What I want it to do: S3 acting as a BT server, sending data, and the Win-App as a client, which is supposed to receive the data.
In Tizen I used the registerRfcommServiceByUUID() function as below:
function publishTransferService() {
if(remoteDevice.isConnented){
console.log("Connection Status: " + remoteDevice.isConnected);
var TRANS_SERVICE_UUID = '5BCE9431-6C75-32AB-AFE0-2EC108A30860';
adapter.registerRFCOMMServiceByUUID(TRANS_SERVICE_UUID, 'My Service', ServiceSuccessCb,
function(e) {
console.log( "Could not register service record, Error: " + e.message);
});
}else{
console.error("Connection Status: " + remoteDevice.isConnected);
}
In C# i try to connect to the service as follows:
//to ulong converted MAC-Address of the Gear
ulong gearBtAddress = 145914022804881;
//create device-instance of the gear
BluetoothDevice gearDevice = await BluetoothDevice.FromBluetoothAddressAsync(gearBtAddress);
//list the services found on the gear and connect to the one with
//the same uuid as in tizen
var gearServices = await gearDevice.GetRfcommServicesAsync();
foreach (var service in gearServices.Services)
{
if(service.ServiceId == RfcommServiceId.FromUuid(Guid.Parse("5BCE9431-6C75-32AB-AFE0-2EC108A30860")))
{
_service = await RfcommDeviceService.FromIdAsync(service.ToString());
}
}
The Problem I am facing is, that the C# won't find the wanted Uuid, although it finds several other uuids. I don't see where it gets lost?
Thanks in advance.
I solved it myself, the problem was, that the UUID was uncached. Adding the following was all to do:
var cacheMode = BluetoothCacheMode.Uncached;
var gearServices = await gearDevice.GetRfcommServicesAsync(cacheMode);

UWP/C# - Issue with AQS and USB Devices

I have an issue with a UWP app that I am trying to write. I am connecting to a custom embedded USB Bulk device that I have programmed (it is actually an out of the box example from Cypress Semiconductor). I am using the WinUSB.sys driver using the embedded MS OS string in the device to allow the device to be used with out having to write a custom INF file to call the WinUSB.sys driver.
In my code, I am using the UsbDevice.GetDeviceSelector method to return an AQS that can then be passed into DeviceInformation.FindAllAsync to begin communicating with the device in my app. I have confirmed that the device shows up in the device manager without any issues, and I have checked in the registry to ensure that it has an Interface GUID. I have a screenshot from USBViewer to show the configuration of the device. This method for finding and connecting with USB devices is from this MSDN example found here.
When I use the UsbDevice.GetDeviceSelector method, it returns a GUID that is not associated with this device. The GUID that it returns is actually associated with Lumia Phones (DEE824EF-729B-4A0E-9C14-B7117D33A817). Because of this, it does not find my device connected to the system.
To troubleshoot, I have both called the DeviceInformation.FindAllAsync with out any arguments to see if my device is listed, and it does find the device (amongst over 1000 other devices that have been connected ever to my machine). I then wrote a custom AQS string without the help of the GetDeviceSelector method, starting with just the GUID. Doing this returned 27 devices, but when I tried to add the VID and PID to this AQS string, nothing returned.
I have also made sure that the device that I want to use is listed in the app manifest by its appropriate VID and PID as this is required for a device with a Custom Class of 0xFF. I have used the Custom USB UWP device example and it can find the device, though it uses a completely different method with a device picker, which I will go to if needed, but this is not my desire as it makes that part of the app not as clean of a solution.
I have posted this question over in the MSDN forums here with more information, but I have not gotten a lot of engagement there. Any help would be appreciated. I know that I must be missing something simple.
Adam
private async void button_Click(object sender, RoutedEventArgs e)
{
//UInt32 vid = 0x04B4;
//UInt32 pid = 0x00F0;
UInt32 vid = uint.Parse(textBox1.Text, System.Globalization.NumberStyles.HexNumber);
UInt32 pid = UInt32.Parse(textBox2.Text, System.Globalization.NumberStyles.HexNumber);
Guid winusbInterfaceGuid = new Guid("a5dcbf10-6530-11d2-901f-00c04fb951ed");
//string aqs = UsbDevice.GetDeviceSelector(vid, pid);
string aqs = UsbDevice.GetDeviceSelector(winusbInterfaceGuid);
var myDevices = await DeviceInformation.FindAllAsync(aqs, null);
//var myDevices = await DeviceInformation.FindAllAsync();
var myDevicesCount = myDevices.Count;
if (myDevicesCount >= 1)
{
textBlock2.Text = "Device Found";
} else
{
textBlock2.Text = "Searching";
await Task.Delay(1000);
textBlock2.Text = "looking for device";
}
}
just dropped you a mail asking about progress (I think, had to guess your mail address), but now it seems I found a solution myself. Please see my answer on UWP app cannot find/connect to USB device
In short, you have to create an inf for installing the winusb driver. I have no clue why, but that did the trick for me (and someone else, see Cannot create UsbDevice from DeviceInformation.Id)
The Guid DEE824EF-729B-4A0E-9C14-B7117D33A817 is actually the standard WinUSB Guid. I don't think it has anything to do with Lumia Phones. I don't know why it is not documented anywhere. I think that the Guid a5dcbf10-6530-11d2-901f-00c04fb951ed you specified is actually a red herring. I mistakenly used that as well, but it just led me down the garden path. It shows up USB interfaces, but I can't connect to them.
You might want to try this class https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net.UWP/UWPUsbDevice.cs .
Here is how it gets the device:
public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
{
var aqsFilter = "System.Devices.InterfaceClassGuid:=\"{DEE824EF-729B-4A0E-9C14-B7117D33A817}\" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND " + $" System.DeviceInterface.WinUsb.UsbVendorId:={vendorId.Value} AND System.DeviceInterface.WinUsb.UsbProductId:={productId.Value}";
var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();
//TODO: return the vid/pid if we can get it from the properties. Also read/write buffer size
var deviceIds = deviceInformationCollection.Select(d => new DeviceDefinition { DeviceId = d.Id, DeviceType = DeviceType.Usb }).ToList();
return deviceIds;
}
This sample connects to a device and I think you'll be able to connect to the device in the same way:
private static async Task InitializeTrezor()
{
//Register the factory for creating Usb devices. This only needs to be done once.
UWPUsbDeviceFactory.Register();
//Register the factory for creating Usb devices. This only needs to be done once.
UWPHidDeviceFactory.Register();
//Note: other custom device types could be added here
//Define the types of devices to search for. This particular device can be connected to via USB, or Hid
var deviceDefinitions = new List<DeviceDefinition>
{
new DeviceDefinition{ DeviceType= DeviceType.Hid, VendorId= 0x534C, ProductId=0x0001, Label="Trezor One Firmware 1.6.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C1, ReadBufferSize=64, WriteBufferSize=64, Label="Trezor One Firmware 1.7.x" },
new DeviceDefinition{ DeviceType= DeviceType.Usb, VendorId= 0x1209, ProductId=0x53C0, ReadBufferSize=64, WriteBufferSize=64, Label="Model T" }
};
//Get the first available device and connect to it
var devices = await DeviceManager.Current.GetDevices(deviceDefinitions);
var trezorDevice = devices.FirstOrDefault();
await trezorDevice.InitializeAsync();
//Create a buffer with 3 bytes (initialize)
var buffer = new byte[64];
buffer[0] = 0x3f;
buffer[1] = 0x23;
buffer[2] = 0x23;
//Write the data to the device
await trezorDevice.WriteAsync(buffer);
//Read the response
var readBuffer = await trezorDevice.ReadAsync();
}
If you connect to the device in this way, you'll get Windows classic, and Android support for free with Device.Net (https://github.com/MelbourneDeveloper/Device.Net)
With Device.net's DeviceManager.Current.GetDevices(deviceDefinitions) using .NET 5 I can't find any device connected to my win10, which can be easily selected by ManagementObjectSearcher:
public List<ManagementBaseObject> GetLogicalDevices()
{
List<ManagementBaseObject> devices = new List<ManagementBaseObject>();
ManagementObjectCollection collection;
ManagementObjectSearcher seacher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM CIM_LogicalDevice");
collection = seacher.Get();
foreach (var device in collection)
{
devices.Add(device);
}
return devices;
}

Connect an C# application thats running sockets using JAVASCRIPT

Hey i was wondering if you could help me
I'm creating an android application in html5 and java script.
There are a server that is created on c# that is listing connection.
I can connect the 2 apps together but get i can get the c# app to reply to my android application using javascript.
here is my server code
public void Listeners()
{
Socket socketForClient = tcpListener.AcceptSocket();
if (socketForClient.Connected)
{
nr_connections = nr_connections + 1;
nr_qry = nr_qry + 1;
SetText("");
SetText("New Connection.");
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
streamWriter.Flush();
string GettheString = streamReader.ReadLine();
if (GettheString == "server_status")
{
SetText("Checking Server Status.");
streamWriter.WriteLine("Online");
streamWriter.Close();
streamReader.Close();
networkStream.Close();
}
}
socketForClient.Close();
SetText("Connection Closed...");
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
nr_connections = nr_connections - 1;
}
and my javascript code
function connect ()
{
try
{
var connection = new WebSocket('ws://105.237.125.247:8');
connection.onopen = function ()
{
connection.send('server_status');
};
connection.onmessage = function (event) {
alert(event.data);
}
}
catch(Exeption)
{
alert("Check Connection");
}
}
Im getting data from the android app but can send back to the javascript file
Web-sockets is a protocol that sits on top of a regular transport (such as a socket); basically, you need a web-socket library. If you are using recent versions of Windows, then much of this is baked into HTTP.SYS, and available via HttpListnener (in particular, AcceptWebSocketAsync on a context). However, alternative web-socket libraries are available, or can be written from scratch if you so choose.

Enumerate available WiFi Printers in my Windows Phone app

I know similar questions have been asked a lot, ie "can I print from my wp8?". Most folks seem content with the simple "no" response. I am looking to add this functionality into my app and I know it can be accomplished at some level - even if I can only support a very minimum printer set for now.
I've looked at the app PrintHand, and it appears to have the capabilities I need: print to wireless and Bluetooth printers.
I've been looking through the Bluetooth scenarios document a bit and I think this might help discover a Bluetooth printer. That's a start. Perhaps it will help in identifying wireless printers also.
I realize I need to start very small with this project and I want to first try to enumerate any wireless printers (I don't have a Bluetooth one yet) available on the current network. Would anybody happen to have a pointer in the right direction on how to get started or better yet, some related sample code?
Thanks so much!
Best I can give is my Github Repo which isn't related to Wifi printers, but Google cloud printing.
There isn't really a .net reference for using Google Cloud Print in their documentation, but the code works in Mono, and should be easy to move over to .NET and hence, Windows Phone.
MonoGCP
I was able to detect a nearby wireless printer using Simple Service Discovery Protocol.
Here is my sample function:
private const string SSDP_IP = "239.255.255.250";
private const string SSDP_PORT = "1900";
public async static void DiscoverAsync2()
{
var multicastIP = new HostName(SSDP_IP);
var found = false;
using (var socket = new DatagramSocket())
{
socket.MessageReceived += (sender, e) =>
{
var reader = e.GetDataReader();
var bytesRemaining = reader.UnconsumedBufferLength;
var receivedString = reader.ReadString(bytesRemaining);
// TODO: something useful with this new info
found = true;
};
await socket.BindEndpointAsync(null, string.Empty);
socket.JoinMulticastGroup(multicastIP);
while (true)
{
found = false;
using (var stream = await socket.GetOutputStreamAsync(multicastIP, SSDP_PORT))
{
var request = new StringBuilder();
request.AppendLine("M-SEARCH * HTTP/1.1");
request.AppendLine("HOST: " + SSDP_IP + ":" + SSDP_PORT);
request.AppendLine("MAN: \"ssdp:discover\"");
request.AppendLine("MX: 3");
request.AppendLine("ST: urn:schemas-upnp-org:device:Printer:1"); // use ssdp:all to get everything
request.AppendLine(); // without this extra blank line, query won't run properly
var buff = Encoding.UTF8.GetBytes(request.ToString());
await stream.WriteAsync(buff.AsBuffer());
await Task.Delay(5000);
if (!found)
break;
}
}
}

Windows 8 app how to connect to Socket server

i have done a server using this example socketAsyncEventArgs
in visual studio 2010 and .net 4.0.
Now i'm trying to connect to it from a windows 8 app using StreamSocket but i'm getting a "Acces denied" message.
here is the Client code:
private StreamSocket streamSocket;
public string Server = "192.168.0.101";
public int Port = 9900;
public async void Connect()
{
streamSocket = new StreamSocket();
Connect();
try
{
await streamSocket.ConnectAsync(
new Windows.Networking.HostName(Server),
Port.ToString()); // getting Acces Denied here
DataReader reader = new DataReader(streamSocket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
var bytesAvailable = await reader.LoadAsync(1000);
var byteArray = new byte[bytesAvailable];
reader.ReadBytes(byteArray);
}
}
catch (Exception e)
{
MessageBox(e.StackTrace);
}
}
How to fix the problem? Is there another way to send and receive messages using this server?
You are probably also seeing the following as part of your error message:
WinRT information: A network capability is required to access this network resource
This is because you need to add a capability to your application that allows you to access local networks. Double click on the Package.appxmanifest file in your project. Click on the Capabilities tab. Add the Private Networks (Client & Server) capability to your project.

Categories